LoginSignup
2
2

More than 3 years have passed since last update.

Pythonにおけるdestructorの挙動を確認

Last updated at Posted at 2020-11-15

サンプルコード class_test.py

class_test.py
class SampleClass:
    num = 0
    def __init__(self, number=1):
        SampleClass.num +=1 # インスタンスが生成される度に、クラス変数numを1インクリメントする
        self.num = number # インスタンス生成時に生成元から受け取った引数numberを、インスタンス変数numに格納する
    def __del__(self):
        SampleClass.num -=1 # インスタンスを削除する度に、クラス変数numを1デクリメントする
        print("このインスタンスを削除しました")

上記のスクリプトファイルを格納したディレクトリと同じ階層で、Python3を起動

Terminal
$ ls
class_test.py
$ cat class_test.py
class SampleClass:
    num = 0
    def __init__(self, number=1):
        SampleClass.num +=1 # インスタンスが生成される度に、クラス変数numを1インクリメントする
        self.num = number # インスタンス生成時に生成元から受け取った引数numberを、インスタンス変数numに格納する
    def __del__(self):
        SampleClass.num -=1 # インスタンスを削除する度に、クラス変数numを1デクリメントする
        print("このインスタンスを削除しました")
$
$ python3
>>>

class_testモジュールをimportして、SampleClassクラスのインスタンスを、生成し、削除してみます。

Terminal
>>> import class_test as ct
>>>
>>> sample_1 = ct.SampleClass()
>>> print(ct.SampleClass.num)
1
>>>
>>> print(sample_1.num)
1
>>>

( ここでのポイント )

  1. SampleClassクラスのインスタンスを1つ生成しました。
  2. インスタンスの個数を管理するクラス変数numの値は、1と表示されました。
  3. また、生成させたインスタンスsample_1が持つインスタンス変数numの値は、コンストラクタのデフォルト引数で設定された1に設定されています。
Terminal
>>> sample_2 = ct.SampleClass(number=4)
>>> print(ct.SampleClass.num)
2
>>> print(sample_2.num)
4
>>>

( ここでのポイント )

  1. SampleClassクラスのインスタンスを、もう1つ生成しました。
  2. インスタンスの個数を管理するクラス変数numの値は、2と表示されました。
  3. また、生成させたインスタンスsample_2が持つインスタンス変数numの値は、sample_2を生成するときに、コンストラクタに引数として渡した4が、設定されています。
Terminal
>>> sample_3 = ct.SampleClass(number=15)
>>> print(ct.SampleClass.num)
3
>>> print(sample_3.num)
15
>>>

( ここでのポイント )

  1. SampleClassクラスのインスタンスを、さらにもう1つ、生成しました。これで、合計3個のインスタンスを生成しました。
  2. インスタンスの個数を管理するクラス変数numの値は、3と表示されました。
  3. また、生成させたインスタンスsample_3が持つインスタンス変数numの値は、sample_3を生成するときに、コンストラクタに引数として渡した15が、設定されています。

ここからが、destructorの挙動の確認になります

Terminal
>>> del sample_2
このインスタンスを削除しました
>>>

( ここでのポイント )

  1. SampleClassクラスのdestructor内に記述した*print("このインスタンスを削除しました")が実行されました。
  2. これで、現在、存在しているインスタンスの数は、2個になりました。
Terminal
>>> print(ct.SampleClass.num)
2
>>> print(sample_1.num)
1
>>> print(sample_3.num)
15
>>> print(sample_2.num)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'sample_2' is not defined
>>>

( ここでのポイント )

  1. インスタンスの個数を管理するクラス変数numの値は、2と表示されました。
  2. sample_2という名前を付けたインスタンスを削除した際に、destructorの中に記述した、クラス変数numを1デクリメントする処理が、きちんと実行されたことがわかります。
  3. このとき、削除したインスタンスとは別の2つのインスタンス(sample_1およびsample_3)のインスタンス変数は、値が変わることなく、意図せぬ影響を受けていないことも、確認できました。

( 追記 )

import文は、以下にしたほうが、コードが短くなる。

import文(変更後)
from class_test import SampleClass
Terminal
>>> from class_test import SampleClass
>>>
>>> sample_1 = SampleClass()
>>> print(SampleClass.num)
1
>>> print(sample_1.num)
1
>>>
>>> sample_2 = SampleClass(number=4)
>>> print(SampleClass.num)
2
>>> print(sample_2.num)
4
>>>

( 参考にしたウェブページ )

  1. Pythonのデストラクタの使い方【初心者向け】
  2. 【Python】インスタンスの個数を求める
  3. Python クラスについて
  4. @ysk24okさんのQiita記事「[Python] importの躓きどころ」
2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2