mypyとTypedDictとtotalオプションについて
pythonでもdictに型を付けたいですね。一応TypedDictという型を定義したいという動きになっています。ちなみにまだこの機能はexperimentalになっているので。mypy_extensionsの方に入っています。
import mypy_extensions as mx class Pair(mx.TypedDict): left: int right: int d0: Pair = {"left": 0, "right": 0} # もしくは d1 = {"left": 0, "right": 0} # type: Pai
mypy_extensions
ついでに寄り道、mypy_extensionsについて、基本的にpythonの型関連の機能は以下の順でnitghtlyからstableというような遷移をします。
- mypy_extensions -- experimental
- typing_extensions -- nightly
- typing -- stable
(併記した修飾子は勝手に付けたものです)
例えば、Protocolなんかはtyping_extensionsですね。
ちなみにこのissueでtyping_extensionsにしようよ。という話が出ています。
TypedDictの定義
TypedDictの型の定義の仕方は、クラス定義likeにやる方法とcollectionsのクラスファクトリーlikeにやる方法の2種類があります。
# クラス定義likeにやる場合 class Pair(mx.TypedDict): left: int right: int # collectionsのクラスファクトリーlikeにやる場合の2種類があります。 Pair = mx.TypedDict("Pair", {"left": int, "right": int})
TypedDictの型の扱われ方
例えば以下のような値がだめになります。
class Pair(mx.TypedDict, total=True): left: int right: int # 未定義のkeyを保持 d0: Pair = {"left": 0, "right": 0, "middle": 0} # 欠損している d1: Pair = {"left": 0} # 型が異なる d2: Pair = {"left": "0", "right": "0"}
欠損値を含む値を許可する(total=False)
欠損値を含んだdictを取り扱いたいときもあると思います。totalというoptionがあります。defaultではTrueです。
このtotalをFalseにすると以下の欠損値を含むコードも全部OKになります。
class Pair(mx.TypedDict, total=Fase): left: int right: int d0: Pair = {"left": 0, "right": 0} d1: Pair = {"left": 0} d2: Pair = {}
欠損値を含んだtypedDictとのintersection(多重継承)
これはいい感じにやってくれます。
import mypy_extensions as mx class Person(mx.TypedDict, total=True): name: str age: int class HasNickname(mx.TypedDict, total=False): nickname: str class PersonHasNickname(Person, HasNickname): pass # ok d0: PersonHasNickname = {"name": "foo", "age": 20, "nickname": "F"} # ok d1: PersonHasNickname = {"name": "foo", "age": 20} # error: Key 'age' missing for TypedDict "PersonHasNickname" d2: PersonHasNickname = {"name": "foo", "nickname": "Fq"}
**kwargsみたいな他の値も取れるようなTypedDictは?
例えば、a:int,b:intという2つのkeyに対しては型が決まっているが、他はanyみたいなdictについての対応のことです。これはまだissueの段階。
(例えば、open api specのformatのサードパーティ用の属性のx-foo-bar
みたいな部分の対応とかで使いそうです)
generics的なものは?
まだ
参考
totalの話は実際の所しっかりドキュメントに書いてあるので。ちゃんと読めば大丈夫。