Pythonの比較的モダンな形でデータを定義できるdataclassesのコードを読んでいたときに、データ構造のフィールドを定義するのに、field(...)という形でクラスのメンバを定義していた。従来のpythonのクラスの書き方では、クラスのプロパティ変数の初期化に__init__
を明示的に読んでいた。これにより、回りくどくはあるが、プロパティ変数は初期化される。一方で、dataclassesを利用したコードでは、フィールドの定義でfield(init=False)
と書くことがある。これによって、このクラスをインスタンス化した時に、このfield(init=False)
で定義したプロパティは、アクセスしようとするとエラーになる。すなわち、そのプロパティが__init__
のような処理が行われていないので、アクセスできない。
正直何をしたくてこれをやるのかわからない。おそらくデフォルト値をfield
で指定するのに関係あるのかもしれない。たとえば、次の記事ではfield(init=False)
で定義したプロパティの値は、インスタンス化した後ほど設定している。
デフォルト値を field で設定するのとは異なるタイミングで初期化を行いたい場合がいつなのか、いまいち想像できない。今読んでいるとあるレポジトリのコードでも上記のようにプロパティをfield(init=False)
で定義しつつ、その後、__post_init__
を用いて値を更新している。
たとえば、外部から少し遅れてやってくる、インスタンス生成時に間に合うかよくわからないデータは、とりあえず、field(init=False)
で初期化させておけば、__post_init__
で値の代入やバリデーション等をすることで、コードの箇所を即時の初期化の箇所と、時間差で初期化される部分とに意味的に分けられていいかもしれない。