特殊メソッド_1(Python_24)

この連載では、Pythonについて色々な形で再学習に取り組んでいます。前回の記事はこちらになります。

hirocom777.hatenadiary.org

前回は、クラスに設定される変数、メソッドについて学びました。

今回は特殊メソッドについて学んでいきたいと思います。

特殊メソッドとは、オブジェクトを直接操作した場合の動作を定義するメソッドです。演算子や組み込み関数などを対象に設定することで、独自のクラスを自分で定義できます。特殊メソッドの名前は、特定の処理を示す名前を、2つのアンダースコア「__」で囲んだものになります。

インスタンスの生成と破棄

すでにご紹介している特殊メソッドにinitメソッドがあります。インスタンス生成後、初期化するために自動で呼び出される特殊メソッドです。実はその前に、インスタンス生成時に実行される特殊メソッドがあります。また、破棄される際に実行される特殊メソッドもあります。今回は、それらの特殊メソッドを見ていきましょう。

initメソッド

initメソッドは、インスタンスを初期化するために自動で呼び出される特殊メソッドです。以下の回で取り上げています。

hirocom777.hatenadiary.org

記述方法は以下の通りです。

class クラス名:
    def __init__(self[, パラメーターの列挙]):
        #処理

呼び出し時は以下のように記述します。

インスタンス.メソッド名(引数の列挙)

newメソッド

initメソッドとは別に、クラスのインスタンス生成する際に呼び出される特殊メソッドがあります。それがnewメソッドです。記述方法は以下の通りです。

    def __new__(cls[, パラメーターの列挙]):
        #処理

呼び出し時は以下のように記述します。

インスタンス.メソッド名(引数の列挙)

記述例を見ていきましょう。

class ClassTest:
    def __new__(cls):
        print('__new__が実行されました')
        self = super().__new__(cls) # インスタンス生成
        return self # 生成したインスタンスを返す
    
    def __init__(self):
        print('__init__が実行されました')

c1 = ClassTest()
# __new__が実行されました と返す
# __init__が実行されました と返す

この様にnewメソッドが実行されてから、initメソッドが実行されています。これは、記述の順番を入れ替えても同じです。initメソッド内の

self = super().__new__(cls) # インスタンス生成

の部分はインスタンスを生成するためのコードです。今はそういうものだと覚えておきましょう。newメソッドを定義すると、そこで作成されたインスタンスinitメソッドへと引き渡されます。これが

return self # 生成したインスタンスを返す

の部分です。ここを省略すると、initメソッドは実行されません。また、これまでご紹介した例でも明らかなのですが、newメソッドを記述しなくてもインスタンスは生成されます。それではnewメソッドには、どういう役目があるのでしょうか。それを説明するには「継承」などの他の機能に関係してきます。別の機会に説明しますので、今はそういうものがあるということを覚えておきましょう。

delメソッド

delメソッドは、インスタンスが破棄された際に自動で呼び出される特殊メソッドです。

    def __del__(self):
        #処理

実行例を見てみましょう。

class ClassTest:
    def __del__(self):
        print('__del__が実行されました')

c1 = ClassTest()
del c1 # __del__が実行されましたを返す

del文はオブジェクトを削除できる命令です。注意しなければならないのは、del文が実行されるとdelメソッドが呼び出される訳ではないということです。オブジェクトを参照する変数がなくなった際に呼び出されます。同じオブジェクトを参照している変数が他にもある場合は呼び出されません。以下の例を見てみましょう。

class ClassTest:
    def __del__(self):
        print('__del__が実行されました')

c1 = ClassTest()
c2 = c1
del c1 # 何も返さない
del c2 # __del__が実行されましたを返す

変数c1を削除しても、変数c2が同じオブジェクトを参照しているので、両方削除しないとdelメソッドは呼び出されません。参照している変数がなくなった際に呼び出されるので、対象の変数が別のオブジェクトを参照した場合も呼び出されます。

class ClassTest:
    def __del__(self):
        print('__del__が実行されました')

c1 = ClassTest()
c1 = 1 # __del__が実行されましたを返す

変数c1に1が代入されたので、delメソッドが呼び出されました。

次回も特殊メソッド

いかがでしょうか。クラスからオブジェクトを作る際の動きが少しわかってきましたね。次回も特殊メソッドです。型変換について見ていきましょう。お楽しみに!!

hirocom777.hatenadiary.org

Python再学習のまとめはこちら!!