Tak's Notebook

Kaggle, Machine Learning, Engineering

呼び出し元の関数の変数を削除したい場合

前回の続き

前回の続き

https://takaishikawa42.hatenablog.com/entry/2019/08/19/090313

結論

関数の中で呼び出した関数内で、呼び出し元の関数の変数を削除したい場合、global 変数を宣言すればアクセスできる

サンプルコード

func 関数内で、func2 の x,y を削除したいときがある。

具体的には、train, validation が大きめなデータで、これを X_train, y_train, X_validation, y_validation に分割することがよくあるかもしれない。

このとき元の train, validation は不要になるうえメモリ的に負担になることがある場合、今回のやり方が役立つかもしれない。

>>> def func(a, b):
...     A = a ** 2
...     B = b ** 2
...     # ここで del x,y したい!
...     return A, B
...
>>> def func2():
...     x = 5
...     y = 10
...     A, B = func(x, y)
...     return A, B
...
>>> func2()
(25, 100)
>>>
>>> globals()
{'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <class '_frozen_importlib.BuiltinImporter'>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, 'func': <function func at 0x7ff5a023d048>, 'func2': <function func2 at 0x7ff5a023d0d0>}

グローバルな名前空間には登録されていないが、 func2 が実行されてから完了するまではメモリに乗っかっていることになる。

funcコメントアウトしている箇所で x,y を del したい場合は以下のように del globals()["x"], globals()["y"] すれば良い。

( この場合コメントアウトしている箇所で del x, y しても、UnboundLocalError: local variable 'x' referenced before assignment というエラーが出る)

>>> def func(a, b):
...     A = a ** 2
...     B = b ** 2
...     del globals()["x"], globals()["y"]
...     return A, B
...
>>> def func2():
...     global x, y
...     x = 5
...     y = 10
...     A, B = func(x,y)
...     return A, B
...
>>> func2()
{'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <class '_frozen_importlib.BuiltinImporter'>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, 'func': <function func at 0x7f90400c2048>, 'func2': <function func2 at 0x7f90400c2158>, 'x': 5, 'y': 10}
{'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <class '_frozen_importlib.BuiltinImporter'>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, 'func': <function func at 0x7f90400c2048>, 'func2': <function func2 at 0x7f90400c2158>}
(25, 100)

グローバルな名前空間からは削除されていることが分かる。

もう少し上手な方法がありそうな気がするので、このあたりのことはもう少し調べたい。