namedtupleによる名前付きタプル

入門Python3 6.14.1


namedtupleを使うことで名前付きのタプルを作ることができます。

from collections import namedtuple

Foo = namedtuple('Foo', ('bar', 'baz'))

まずはこのコードでbarとbazのプロパティを持つFooクラスが生成されます。


次にFooオブジェクトを生成。namedtupleの第二引数に指定した順に引数を渡します。

foo = Foo(1,2)

もしくは

foo = Foo(bar=1,baz=2)

といった感じで初期化します。

これで通常のタプルのように[]演算子によるアクセスも可能だし、オブジェクトのプロパティの用にアクセスも可能となります。

from collections import namedtuple

Foo = namedtuple('Foo', ('bar', 'baz'))

foo = Foo(bar=1,baz=2)

# タプルのようにアクセス
print(foo[0])
print(foo[1])

# プロパティのようにアクセス
print(foo.bar)
print(foo.baz)

# イテレータでアクセス
for item in foo:
    print(item)
$ py main.py
1
2
1
2
1
2

またタプルと同じくイミュータブルなので変更は不可です

from collections import namedtuple

Foo = namedtuple('Foo', ('bar', 'baz'))

foo = Foo(bar=1,baz=2)

foo.bar = "aaa"
$ py main.py
Traceback (most recent call last):
  File "main.py", line 8, in <module>
    foo.bar = "aaa"
AttributeError: can't set attribute

便利ですね。


もしこのFooクラスをnamedtupleを使わずに実装した場合どうなるか、試しに実装してみました。

class Foo():
    def __init__(self,bar,baz):
        self.__list = (bar,baz)
        self.__counter = 0
    
    def __getitem__(self,key):
        return self.__list[key]
    
    @property
    def bar(self):
        return self.__list[0]
    
    @property
    def baz(self):
        return self.__list[1]
    
    def __iter__(self):
        self.__counter = 0
        return self
    
    def __next__(self):
        self.__counter += 1
        
        if ( self.__counter > len(self.__list) ):
            raise StopIteration
        
        return self.__list[self.__counter - 1]

こんな感じになりました。

実際にはnamedtupleはもっと多機能なので、こんなコード毎回書いてられないですね。活用しましょう。