namedtuple は tuple を継承したものです。
>>> from collections import namedtuple
>>> Point = namedtuple('Point', 'x y z')
# namedtuple は tuple のサブクラス
>>> issubclass(Point, tuple)
True
当然、tuple のアトリビュートは namedtuple にも引き継がれます。
# tuple のアトリビュート >>> dir(tuple) ['__add__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '_ _eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs __', '__gt__', '__hash__', '__init__', '__iter__', '__le__', '__len__', '__lt__' , '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__ rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'count', 'i ndex'] # namedtuple のアトリビュート >>> dir(Point) ['__add__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '_ _eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs __', '__gt__', '__hash__', '__init__', '__iter__', '__le__', '__len__', '__lt__' , '__module__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', ' __repr__', '__rmul__', '__setattr__', '__sizeof__', '__slots__', '__str__', '__s ubclasshook__', '_asdict', '_fields', '_make', '_replace', '_source', 'count', ' index', 'x', 'y', 'z']
ここで注目すべきは、tuple は count と index という _(アンダーバー)で始まらないアトリビュートを2つ持っている点です。即ち、namedtuple の要素名として count か index を指定した場合、その namedtuple は親クラスである tuple のインターフェースを変えてしまった良くないサブクラス、ということになります。
結論として、namedtuple の要素名として count と index は使うべきではありません。
>>> WrongNames = namedtuple('WrongNames', 'count index')
>>> wrong_names = WrongNames(1, 2)
# count は要素名になってしまった
>>> wrong_names.count
1
# tuple の count() を期待するとエラー
>>> wrong_names.count(1)
Traceback (most recent call last):
File "", line 1, in
TypeError: 'int' object is not callable
# index は要素名になってしまった
>>> wrong_names.index
2
# tuple の index() を期待するとエラー
>>> wrong_names.index(1)
Traceback (most recent call last):
File "", line 1, in
TypeError: 'int' object is not callable
0 件のコメント:
コメントを投稿