¿Cómo comprobar si un objeto es una instancia de una namedtuple?
-
24-09-2019 - |
Pregunta
¿Cómo puedo comprobar si un objeto es una instancia de un Named tupla ?
Solución
Acceso a la función collections.namedtuple
le da un nuevo tipo que es una subclase de tuple
(y no otras clases) con un _fields
nombrado miembro que es una tupla cuyos elementos son todas las cadenas. Por lo que podría comprobar todas y cada una de estas cosas:
def isnamedtupleinstance(x):
t = type(x)
b = t.__bases__
if len(b) != 1 or b[0] != tuple: return False
f = getattr(t, '_fields', None)
if not isinstance(f, tuple): return False
return all(type(n)==str for n in f)
No es posible obtener un falso positivo de esto, pero sólo si alguien va a salir de su manera de hacer un tipo que se parece un mucho como una tupla llamada, pero no es uno ;-) .
Otros consejos
Me da cuenta de esto es viejo, pero he encontrado esto útil:
from collections import namedtuple
SomeThing = namedtuple('SomeThing', 'prop another_prop')
SomeOtherThing = namedtuple('SomeOtherThing', 'prop still_another_prop')
a = SomeThing(1, 2)
isinstance(a, SomeThing) # True
isinstance(a, SomeOtherThing) # False
Si es necesario comprobar antes de llamar a funciones específicas namedtuple en él, entonces simplemente llamar y detectar la excepción en su lugar. Esa es la mejor forma de hacerlo en Python.
La mejora en lo que Lutz colocado:
def isinstance_namedtuple(x):
return (isinstance(x, tuple) and
isinstance(getattr(x, '__dict__', None), collections.Mapping) and
getattr(x, '_fields', None) is not None)
Yo uso
isinstance(x, tuple) and isinstance(x.__dict__, collections.abc.Mapping)
lo que me parece mejor reflejan el aspecto diccionario de la naturaleza de tuplas con nombre. Parece ser robusto frente a un futuro imaginable también cambia y puede que al trabajo con muchas clases namedtuple-ish de terceros, si tales cosas suceden de existir.