2.20. 最初のクラス

クラス は、データと、そのデータに作用する関数を、1 つの名前のもとにまとめます。いくつかの状態がまとまりとして属していて、スクリプト内のほとんどの関数がその同じ値の集合を引数として取る場合、クラスを使う価値があります。

2.20.1. class キーワード

キーワードは class です。本体には、新しいインスタンスが作成されるたびに実行される __init__ メソッドが含まれます。

class Point:
    def __init__(self, x, y):
        self.x = x
        self.y = y

p = Point(3, 4)
print(p.x, p.y)

出力:

3 4

Point がクラスで、p はその インスタンス です。Point(3, 4) という呼び出しの括弧が __init__ を呼び出し、それが引数を新しいインスタンスの属性に割り当てます。self はインスタンスを表す慣例的な名前です。self.x は、インスタンスの残りのメソッドが読み取る属性を設定します。

2.20.2. いつクラスを使うか

次の条件が同時に当てはまるときにクラスを使ってください。

  • 関連するいくつかの値がどこへ行くにも一緒に移動する(点の xy、センサー読み取り値の値・単位・タイムスタンプなど)。

  • 複数の関数がその同じ値の集合を受け取り、それらを操作する。

  • これらのまとまりを互いに区別しながら、一度に複数生かしておくことが役立つ。

データが使い捨てなら、通常は素の dicttuple で十分です。定数のまとまりが 1 つだけ必要なら、モジュールレベルの変数で構いません。クラスはデフォルトのコンテナではありません -- 状態と振る舞いが一緒にまとまっていたいときに、その役割を勝ち取るのです。

2.20.3. __init__ が行うこと

__init__ は単なる通常のメソッドです。その中で self に割り当てられたものはすべて、新しいインスタンスの属性になります。

class Sensor:
    def __init__(self, name, unit):
        self.name = name
        self.unit = unit
        self.readings = []

temp = Sensor("temperature", "C")
print(temp.name, temp.unit, temp.readings)

出力:

temperature C []

readings は空のリストに初期化されます -- 各新規インスタンスは、共有されたものではなく、それぞれ独自のリストを得ます。self に割り当てられないものはすべて __init__ のローカルであり、それが戻ると消えます。