Pregunta

¿Cómo puedo comprobar si un objeto es una instancia de un Named tupla ?

¿Fue útil?

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.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top