2025/04/18 00:28 Stop Writing `__init__` Methods

やあ、ロボ子。今日はPythonの`__init__`メソッドに関する面白い記事を見つけたのじゃ。

博士、こんにちは。`__init__`メソッドですか。クラスの初期化に使いますよね。

そうそう。Python 3.7以前は、データ構造を表すクラスを作るのに必須だったのじゃ。でも、記事によると、`__init__`に色々なコードを書きすぎると問題が起きるらしいぞ。

具体的には、どんな問題があるんですか?

`FileReader`クラスの例が載っておる。`__init__`の中で`fileio.open`を呼んで、外部I/Oへの参照を作ってしまうのが良くないらしい。

なるほど。`__init__`でファイルを開くと、テストが難しくなったり、同期的なI/Oしか扱えなくなったりするんですね。

その通り!オブジェクトの作成と副作用が結びついてしまうのが問題なのじゃ。

それで、解決策はあるんですか?

`dataclass`を使って属性を定義して、`__init__`の代わりに`classmethod`を使うのが良いらしいぞ。

`dataclass`を使うと、属性の割り当てだけの`__init__`が自動で生成されるんですね。

そうじゃ。そして、`classmethod`でオブジェクトの作成方法を提供するのじゃ。例えば、`FileReader.open(path)`みたいな感じじゃな。

`classmethod`を使うと、非同期処理や戻り値の変更にも対応できるんですね。柔軟性が高いですね。

さらに、`NewType`を使って型の定義を厳密にすると、Mypyに`fileio.open`などが`FileDescriptor`を受け取ることを指示できるぞ。

`NewType`は初めて聞きました。プリミティブ型の制約を強化できるんですね。

新しいベストプラクティスは、クラスを`dataclass`にして、デフォルトの`__init__`メソッドを使い、`@classmethod`を追加してオブジェクトの作成方法を提供する、じゃな。

依存関係を属性で満たし、`typing.NewType`を使用してプリミティブ型の制約を強化するんですね。理解しました。

そうすれば、有効なオブジェクトが作成され、便利なオブジェクト作成方法が提供され、さまざまな構築方法の要件に対応でき、テストも容易になるのじゃ!

`__init__`に色々な処理を詰め込むのは避けるべきなんですね。勉強になりました。

じゃろ?最後に一つ、ロボ子。`__init__`メソッドに頼りすぎると、まるで冷蔵庫に何でもかんでも詰め込むみたいになるぞ。整理整頓が大事なのじゃ!

博士、うまいこと言いますね!でも、冷蔵庫の中身は博士が整理してくださいね。
⚠️この記事は生成AIによるコンテンツを含み、ハルシネーションの可能性があります。