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

#サンプルコード *class_test.py*

```Python3: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を起動


```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*クラスのインスタンスを、生成し、削除してみます。

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

####（ ここでのポイント ）
1. *SampleClass*クラスのインスタンスを１つ生成しました。
2. インスタンスの個数を管理するクラス変数*num*の値は、1と表示されました。
3. また、生成させたインスタンス*sample_1*が持つインスタンス変数*num*の値は、コンストラクタのデフォルト引数で設定された1に設定されています。

```Python3:Terminal
>>> sample_2 = ct.SampleClass(number=4)
>>> print(ct.SampleClass.num)
2
>>> print(sample_2.num)
4
>>>
```

####（ ここでのポイント ）

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


```Python3:Terminal
>>> sample_3 = ct.SampleClass(number=15)
>>> print(ct.SampleClass.num)
3
>>> print(sample_3.num)
15
>>>
```

####（ ここでのポイント ）

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

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

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

####（ ここでのポイント ）

1. *SampleClass*クラスの*destructor*内に記述した*print("このインスタンスを削除しました")が実行されました。
2. これで、現在、存在しているインスタンスの数は、2個になりました。

```Python3: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*文は、以下にしたほうが、コードが短くなる。

```Python3:import文（変更後）
from class_test import SampleClass
```

```Python3: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のデストラクタの使い方【初心者向け】](https://techacademy.jp/magazine/19127)
2. [【Python】インスタンスの個数を求める](https://algorithm.joho.info/programming/python-instance-number/)
3. [Python クラスについて](https://qiita.com/motoki1990/items/376fc1d1f3d59c960f5c)
4. [@ysk24okさんのQiita記事「[Python] importの躓きどころ」](https://qiita.com/ysk24ok/items/2711295d83218c699276)