環境
- Python3.11.2
起きたこと
dataclassでクラスTask
を定義しています。フィールドframe_count
にはデフォルト値を指定したいです。
In [48]: @dataclass
...: class Task:
...: name: str
...: frame_count: int = 10
...:
In [49]: Task("foo", 5)
Out[49]: Task(name='foo', frame_count=5)
「frmae_count
には10
を代入しているので、型ヒントを指定しなくてもmypyはint
と推論してくれるだろう」と思い、型アノテーションint
を取り除いてみました。
すると、インスタンス生成時に「引数が多すぎる」というTypeErrorが発生しました。
In [51]: @dataclass
...: class Task:
...: name: str
...: frame_count = 10
...:
In [52]: Task("foo", 5)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
Cell In[52], line 1
----> 1 Task("foo", 5)
TypeError: Task.__init__() takes 2 positional arguments but 3 were given
原因
型アノテーションがないとdataclassのフィールドして扱われないから。
dataclasses.dataclassには、以下の様に記載されていました。
dataclass() デコレータは、フィールド を探すためにクラスを検査します。 フィールド は 型アノテーション を持つクラス変数として定義されます。 後述する2つの例外を除き、 dataclass() は変数アノテーションで指定した型を検査しません。
補足:型アノテーションは何でもよい
dataclassのフィールドとして利用するには型ヒントは必須ですが、Pythonは型を検査しないので、どんな型ヒントでもよいです。もちろんmypyなどには怒られると思いますが。
In [53]: @dataclass
...: class Task:
...: name: ...
...: frame_count: ... = 10
...:
In [54]: Task("foo", 5)
Out[54]: Task(name='foo', frame_count=5)