51

オブジェクトがNamed tupleのインスタンスであるかどうかを確認するにはどうすればよいですか?

4

7 に答える 7

52

関数 を呼び出すと、項目がすべて文字列であるタプルであるという名前のメンバーを持つ (他のクラスではない) の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)

これにより誤検知が発生する可能性がありますが、名前付きタプルによく似ているが名前付きタプルではない型を誰かが作成しようとしている場合に限られます;-)。

于 2010-01-30T04:21:18.073 に答える
29

オブジェクトが特定の名前付きタプルのインスタンスであるかどうかを判断したい場合は、次のようにすることができます。

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
于 2016-12-29T00:28:07.930 に答える
5

3.7+

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

于 2020-07-02T08:56:04.853 に答える
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)                                  
于 2018-03-16T16:54:06.040 に答える
4

その上でnamedtuple固有の関数を呼び出す前にチェックする必要がある場合は、代わりにそれらを呼び出して例外をキャッチしてください。これは、Python でそれを行うための推奨される方法です。

于 2010-01-30T04:22:15.780 に答える
1

私が使う

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

これは、名前付きタプルの性質の辞書的側面を最もよく反映しているように思えます。考えられる将来の変更に対しても堅牢に見えます。また、そのようなものが存在する場合、多くのサードパーティの名前付きタプル風のクラスでも動作する可能性があります。

于 2014-06-20T16:05:52.173 に答える
0

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":

于 2020-07-08T09:12:27.827 に答える