コンストラクタとデストラクタ

コンストラクタとデストラクタ

コンストラクタ (イニシャライザ)

 __init__(self, [, ...]) はインスタンス生成時に自動的に呼び出されて実行される初期化メソッドで、コンストラクタ またはイニシャライザとよばれます。

# CONSTRUCTOR

# In[1]

# インスタンス生成と同時に"Hello!"を表示するクラス
class Hello:
     def __init__(self):
        print("Hello!")

# Helloクラスのインスタンスを生成
my_object = Hello()

# Hello!

 __init__() の戻り値は常に None なので、return 構文に None 以外を指定すると TypeError が送出されます。

# In[2]

# クラスを定義
class Return_value:
    def __init__(self, value):
        return value

# インスタンスを生成
x = Return_value(10)

# TypeError: __init__() should return None, not 'int'

 インスタンス生成時に受け取った引数 (インスタンス変数) は __init__() に記述しておきます。

# In[3]

# Squareクラスを定義
class Square:
    def __init__(self, x):
        
        # 引数を2乗してオブジェクトの属性値に格納する
        self.value = x ** 2

# Squareクラスのインスタンスを生成
my_object = Square(5)

# value属性を表示
print(my_object.value)
# 25

デストラクタ (ファイナライザ)

 __del__(self) はインスタンスが破棄される (リソースが解放される) ときに呼び出されるメソッドです。コンストラクタと対になるメソッドで、デストラクタ またはファイナライザとよばれます。たとえば、次のようなプロフィール管理クラスを定義したとします。

# DESTRUCTOR

# In[1]

# プロフィール管理クラス
class Profile:
    def __init__(self, name, age, sex):
        self.name = name
        self.age = age
        self.sex = sex
    
    # デストラクタ
    def __del__(self):
        print("インスタンスは破棄されました")

 Profile クラスのインスタンスを生成して、name 属性を参照してみます。

# In[2]

# Profileクラスのインスタンスを生成
mariko = Profile("刑部真理子", 38, "女性")

# インスタンスのname属性を表示
print(mariko.name)
# 刑部真理子

 del 構文を使うと、インスタンスを明示的に破棄できます。

del mariko
# インスタンスは破棄されました

 再度、name 属性を参照しようと試みても、すでにインスタンスが消失しているので NameError が送出されます (そのような名前のオブジェクトは存在しないという意味です)。

# In[3]

# インスタンスのname属性を表示
print(mariko.name)
# NameError: name 'mariko' is not defined

 del で明示的に宣言しなくてもインスタンスが破棄されることがあります。
 もう1つ Profile クラスのインスタンスを作成してみます。

# In[4]

# Profileクラスのインスタンスを生成
suzune = Profile("城戸涼音", 26, "女性")

# インスタンスのname属性を表示
print(suzune.name)
# 城戸涼音

 変数 suzune に別のオブジェクトへの参照を割り当てると、元々参照していたオブジェクトは破棄されます。

# In[5]

suzune = 100
# インスタンスは破棄されました