概要
前にcollections.namedtupleについての記事を書いていたのですが
以下のページをみてたら、typing.NamedTupleというものもあるとのこと。
pythonのドキュメントを見ると、collections.namedtupleの型付き版とのこと。
C#とかに慣れている人だと、こっちの方が親近感が湧きますね。
使い方は、collections.namedtupleで
MyData = collections.namedtuple('MyData', ['id', 'name', 'age'])
とする場合、typing.NamedTupleだと
class MyData(typing.NamedTuple): id: int name: str age: int
となります。構築される中身はどちらも全く同じになります。
明示的に型ヒントを付けられるのがいい感じ。また当然ですが
ここで付与している型ヒントは、なんら強制力を持ちません。
あくまで型ヒント。なので、どんな値でも入ります。
collections.namedtupleがイミュータブルなのと同じで
typing.NamedTupleもイミュータブルです。
サンプル
import collections import dis import sys import typing class MyData(typing.NamedTuple): id: int name: str age: int MyData2 = collections.namedtuple('MyData2', 'id name age') m1 = MyData(1, 'name01', 33) m2 = MyData2(1, 'name22', 22) pr('typing.NamedTuple', m1) pr('collections.namedtuple', m2) pr('getsizeof(typing.NamedTuple)', sys.getsizeof(m1)) pr('getsizeof(collections.namedtuple)', sys.getsizeof(m2)) try: m1.name = 'name02' except AttributeError as e: pr('typing.NamedTuple is immutable', e) try: m2.name = 'name02' except AttributeError as e: pr('collections.namedtuple is immutable', e) hr('dis.dis(MyData)') dis.dis(MyData.__new__) hr('dis.dis(MyData2)') dis.dis(MyData2.__new__)
実行すると以下のようになります。
typing.NamedTuple=MyData(id=1, name='name01', age=33) collections.namedtuple=MyData2(id=1, name='name22', age=22) getsizeof(typing.NamedTuple)=72 getsizeof(collections.namedtuple)=72 typing.NamedTuple is immutable=AttributeError("can't set attribute",) collections.namedtuple is immutable=AttributeError("can't set attribute",) ----------------dis.dis(MyData)---------------- 14 0 LOAD_GLOBAL 0 (_tuple) 2 LOAD_ATTR 1 (__new__) 4 LOAD_FAST 0 (_cls) 6 LOAD_FAST 1 (id) 8 LOAD_FAST 2 (name) 10 LOAD_FAST 3 (age) 12 BUILD_TUPLE 3 14 CALL_FUNCTION 2 16 RETURN_VALUE ----------------dis.dis(MyData2)---------------- 14 0 LOAD_GLOBAL 0 (_tuple) 2 LOAD_ATTR 1 (__new__) 4 LOAD_FAST 0 (_cls) 6 LOAD_FAST 1 (id) 8 LOAD_FAST 2 (name) 10 LOAD_FAST 3 (age) 12 BUILD_TUPLE 3 14 CALL_FUNCTION 2 16 RETURN_VALUE
バイトコードを表示しても、全く同じですね。
ソースは以下の場所でも見れます。
try-python/typing01.py at master · devlights/try-python · GitHub
参考情報
Records, Structs, and Data Transfer Objects in Python – dbader.org
26.1. typing — 型ヒントのサポート — Python 3.6.1 ドキュメント
過去の記事については、以下のページからご参照下さい。
- いろいろ備忘録日記まとめ
サンプルコードは、以下の場所で公開しています。
- いろいろ備忘録日記サンプルソース置き場