クラスの初期化メソッドについて

入門コースの難所でもあるクラスについて理解を深めるため、今日は初期化メソッドの特徴やメリットについて考えてみたいと思います。

初期化メソッドとはクラスの中でdef __init__(self):などのように書くメソッドのことです。

前提

  • FamiResクラスは「フォミレスの設計図」
  • ファミレスを展開するには、各地域の「支店名」と「オーナー名」が必須
  • 2つのインスタンスを生成

初期化メソッドを使わないクラスの例

# 初期化メソッドを使わない例
class FamiRes1:
    def set_owner(self, owner):
        self.owner = f"{owner}オーナー"

    def set_branch(self, branch):
        self.branch = f"{branch}支店"

tokyo_store = FamiRes1()
tokyo_store.set_owner("藤本")  # インスタンス変数をセットするためにメソッドを実行(以下同様)
tokyo_store.set_branch("東京")

kanagawa_store = FamiRes1()
kanagawa_store.set_owner("田中")
kanagawa_store.set_branch("神奈川")

print(tokyo_store.owner, tokyo_store.branch)
print(kanagawa_store.owner, kanagawa_store.branch)


# 実行結果
# 藤本オーナー 東京支店
# 田中オーナー 神奈川支店

上記のようにすると、インスタンス変数をメソッドで設定する場合、必ずメソッドを実行する必要があります。では初期化メソッドを記載する場合ではどうなるかを下記に掲載します。

初期化メソッドを使うクラスの例

# 初期化メソッドを使う例
class FamiRes2:
    def __init__(self, owner, branch):  # 初期化メソッド
        self.owner = f"{owner}オーナー"
        self.branch = f"{branch}支店"

tokyo_store = FamiRes2("藤本", "東京")

kanagawa_store = FamiRes2("田中", "神奈川")

print(tokyo_store.owner, tokyo_store.branch)
print(kanagawa_store.owner, kanagawa_store.branch)

# 実行結果
# 藤本オーナー 東京支店
# 田中オーナー 神奈川支店

初期化メソッドの特徴

まず、初期化メソッドの固有の機能をみてみます。

  1. インスタンス作成時に自動的に呼ばれる。
  2. インスタンス化以降は呼ばれない。
  3. 初期化メソッドに引数がある場合は、インスタンス作成時に引数を設定する必要がある。

初期化メソッドのメリット

コードだけをみると、初期化メソッドがある場合、「コード量が少なくてすみそう」というのがあげられます。こちらはそうかもしれませんし、書き方によっては対して差はないかもしれません。

ここで上記の特徴からメリットを考えてみたいと思います。

  1. メソッドの実行忘れを防げる。
  2. インスタンス作成時しか使わないことが明確になる。
  3. インスタンス変数への値の設定を強制できる。

特徴とメリットを考えてみると…

例で言えば、初期化メソッドを使用せずにインスタンス変数を設定する場合、set_ownerメソッドやset_branchメソッドがいつ呼ばれるのかは任意となってしまいます。さらに言えば、使う人によってはそもそも使用しないことすらあり得るかもしれません。FamiRes2の初期化メソッドではインスタンス生成時に値の設定を強制できるのに対し、FamiRes1クラスの通常メソッドはそうではありません。ということはFamiRes1クラスのインスタンスによっては、オーナー名や支店名の値を持っていないインスタンスがが存在し得るということになります。

インスタンス変数自体は事前に定義する必要がありません。だからこそ、初期化メソッド内で値の設定を強制しないと、設定していない人(インスタンス)や設定している人(インスタンス)でばらばらになります。

FamiRes1クラスにおいて、set_owner()メソッドを実行しないまま、owner名を呼び出す場合を想像してみましょう。

tokyo_store = FamiRes1()  # 初期化メソッドを使わないクラスをインスタンス化
print(tokyo_store.owner)  # set_owner()メソッドを実行せずにownerを呼び出す

# 実行すると owner が定義されていないのでエラーになります。

このインスタンス変数がクラス内の処理で重要な役割を果たす場合はより一層「値の設定の強制」が大切です。なぜなら、重要なインスタンス変数を設定しなくてもよければ、そもそもこのクラスを使う理由がなくなるかもしれないからです。

以上、初期化メソッドについて考えてみました〜