Come verificare se un oggetto è un'istanza di un namedtuple?
-
24-09-2019 - |
Domanda
Come si controlla se un oggetto è un'istanza di una named tupla ?
Soluzione
La chiamata alla funzione collections.namedtuple
ti dà un nuovo tipo che è una sottoclasse di tuple
(e non altre classi) con un nome _fields
membro che è una tupla i cui elementi sono tutte le stringhe. Così si potrebbe verificare la presenza di tutti e di ciascuno di queste cose:
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)
E 'possibile ottenere un falso positivo da questo, ma solo se qualcuno di andare fuori del loro modo di fare un tipo che sembra un molto come una tupla di nome, ma non è uno ;-) .
Altri suggerimenti
mi rendo conto che è vecchio, ma ho trovato questo 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
Se avete bisogno di controllare prima di chiamare funzioni namedtuple specifiche su di esso, poi basta chiamarli e intercettare l'eccezione invece. Questo è il modo migliore per farlo in python.
Il miglioramento su ciò che Lutz ha scritto:
def isinstance_namedtuple(x):
return (isinstance(x, tuple) and
isinstance(getattr(x, '__dict__', None), collections.Mapping) and
getattr(x, '_fields', None) is not None)
Io uso
isinstance(x, tuple) and isinstance(x.__dict__, collections.abc.Mapping)
che a me sembra meglio riflettere l'aspetto dizionario della natura di tuple nome. Sembra robusta contro un futuro immaginabile cambia troppo e potrebbe funzionare anche con molte classi namedtuple-ish di terze parti, se queste cose accadono di esistere.