Comment vérifier si un objet est une instance d'un namedtuple?
-
24-09-2019 - |
Question
Comment puis-je vérifier si un objet est une instance d'un Nommé tuple ?
La solution
L'appel de la Fonction collections.namedtuple
vous donne un nouveau type qui est une sous-classe de tuple
(et aucune autre classe) avec un membre nommé _fields
qui est un tuple dont les éléments sont toutes les chaînes. Donc, vous pouvez vérifier pour chacun de ces choses:
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)
Il est possible d'obtenir un faux positif de cela, mais seulement si quelqu'un va sortir de leur façon de faire un type qui ressemble un beaucoup comme un tuple nommé, mais ne fait pas partie ;-) .
Autres conseils
Je sais que c'est vieux, mais je trouve cela utile:
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 vous devez vérifier avant d'appeler namedtuple fonctions spécifiques à ce sujet, alors il suffit de les appeler et attraper l'exception au lieu. C'est la meilleure façon de le faire en python.
L'amélioration de ce que Lutz affiché:
def isinstance_namedtuple(x):
return (isinstance(x, tuple) and
isinstance(getattr(x, '__dict__', None), collections.Mapping) and
getattr(x, '_fields', None) is not None)
J'utilise
isinstance(x, tuple) and isinstance(x.__dict__, collections.abc.Mapping)
qui me semble mieux refléter l'aspect dictionnaire de la nature de tuples nommés. Il semble robuste contre un avenir envisageable change aussi, et peut aussi travailler avec de nombreuses classes de namedtuple-ish tiers, si ces choses arrivent à exister.