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はもっと多機能なので、こんなコード毎回書いてられないですね。活用しましょう。