Pythonのtyping.Tupleで可変長のタプルとしてアノテーションする
mypy使っていますか?私は最近プロジェクトにも入れて使っています。
ですが typing.Tuple の扱いがうまく分かっていなくて、こんなプログラムを書いていました。
# 悪い例 import typing my_tuple: typing.Tuple[str] = () my_tuple = ('mymodule.myfunc', 'mymodule.myfunc2')
このプログラムを mypy で型チェックするとこんなエラーがでます。
$ mypy ./tuple.py tuple.py:4: error: Incompatible types in assignment (expression has type "Tuple[]", variable has type "Tuple[str]") tuple.py:6: error: Incompatible types in assignment (expression has type "Tuple[str, str]", variable has type "Tuple[str]")
Tuple のアノテーションは固定長で使うように想定されているようです。
例えば Tuple[str, int, int, int] のようにして、 ('名前', 1991, 11, 5) のような値を入れる使い方でしょうか。
ちょうど、 NamedTuple に近い印象で、1つの「何か」を1つのタプルで表すような使い方です。
可変長のタプルでアノテーションする
可変長のタプルをアノテーションするには Tuple[str, ...] のようにEllipsis ... を使って明示します 。
# 良い例 import typing my_tuple: typing.Tuple[str, ...] = () my_tuple = ('mymodule.myfunc', 'mymodule.myfunc2')
typing — Support for type hints — Python 3.7.1 documentation
これでうまく動作します。
例えば以下のようにテンプレートになる基底クラスで、期待する設定値のアノテーションをしておくこともできます。
class MyBase: SOME_FIELDS: typing.ClassVar[typing.Tuple[str, ...]] = ()
typing.List はもともと可変長の値でチェックできますが、タプルのときは typing.Tuple[str, ...] のようにEllipsisを書くと可変長と解釈されます。