How do I check if an object is an instance of a Named tuple?
问题:
回答1:
Calling the function collections.namedtuple
gives you a new type that's a subclass of tuple
(and no other classes) with a member named _fields
that's a tuple whose items are all strings. So you could check for each and every one of these things:
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)
it IS possible to get a false positive from this, but only if somebody's going out of their way to make a type that looks a lot like a named tuple but isn't one;-).
回答2:
I realize this is old, but I found this useful:
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
回答3:
If you need to check before calling namedtuple specific functions on it, then just call them and catch the exception instead. That's the preferred way to do it in python.
回答4:
Improving on what Lutz posted:
def isinstance_namedtuple(x):
return (isinstance(x, tuple) and
isinstance(getattr(x, '__dict__', None), collections.Mapping) and
getattr(x, '_fields', None) is not None)
回答5:
I use
isinstance(x, tuple) and isinstance(x.__dict__, collections.abc.Mapping)
which to me appears to best reflect the dictionary aspect of the nature of named tuples. It appears robust against some conceivable future changes too and might also work with many third-party namedtuple-ish classes, if such things happen to exist.