如何检查一个对象是否是namedtuple的实例?

问题描述 投票:0回答:8

如何检查对象是否是命名元组的实例?

python introspection namedtuple isinstance
8个回答
58
投票

调用 function

collections.namedtuple
会为您提供一个新类型,它是
tuple
(没有其他类)的子类,其中包含名为
_fields
的成员,该成员是一个元组,其项目都是字符串。 所以你可以检查每一项:

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)

有可能从中得到误报,但前提是有人不遗余力地创建一种看起来很多像命名元组但实际上不是一个的类型;-)。


36
投票

如果你想判断一个对象是否是特定namedtuple的实例,你可以这样做:

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

11
投票

3.7+

def isinstance_namedtuple(obj) -> bool:
    return (
            isinstance(obj, tuple) and
            hasattr(obj, '_asdict') and
            hasattr(obj, '_fields')
    )


3
投票

如果您需要在调用namedtuple特定函数之前进行检查,那么只需调用它们并捕获异常即可。这是在 python 中执行此操作的首选方法。


3
投票

改进 Lutz 发布的内容:

def isinstance_namedtuple(x):                                                               
  return (isinstance(x, tuple) and                                                  
          isinstance(getattr(x, '__dict__', None), collections.Mapping) and         
          getattr(x, '_fields', None) is not None)                                  

2
投票

我用

isinstance(x, tuple) and isinstance(x.__dict__, collections.abc.Mapping)

在我看来,这似乎最能反映命名元组性质的字典方面。 它对于一些可以想象的未来变化似乎也很强大,并且也可能与许多第三方命名元组类一起使用,如果这样的事情碰巧存在的话。


0
投票

namedtuple 具有

_fields
属性。

我用:

def is_namedtuple(v: Any):
    return isinstance(v, tuple) and hasattr(v, "_fields")

-1
投票

IMO 这可能是 Python 3.6 及更高版本的最佳解决方案。

您可以在实例化命名元组时设置自定义

__module__
,并稍后检查它

from collections import namedtuple

# module parameter added in python 3.6
namespace = namedtuple("namespace", "foo bar", module=__name__ + ".namespace")

然后检查

__module__

if getattr(x, "__module__", None) == "xxxx.namespace":

© www.soinside.com 2019 - 2024. All rights reserved.