前回の続き
前回の続き
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)
グローバルな名前空間からは削除されていることが分かる。
もう少し上手な方法がありそうな気がするので、このあたりのことはもう少し調べたい。