在PythonPDB下,当在_del_____方法中到达断点时,如果gc是原因,堆栈会是什么样子?
情况:我在在PythonPDB下,当在_del_____方法中到达断点时,如果gc是原因,堆栈会是什么样子?,python,garbage-collection,pdb,Python,Garbage Collection,Pdb,情况:我在\uu del\uu方法中放置了一个断点。当使用del显式删除对象时,堆栈清楚地表明del是调用\uuuu del\uuu的原因 但是,如果由于超出范围/垃圾收集而调用了\uu del\uu,堆栈会是什么样子?是否很清楚gc在堆栈上,或者它看起来像执行gc时代码所在的任何点 或者这在其他方面是非理性的?经过一些基础研究,根据下面的脚本及其附带的输出,至少对CPython(由Anaconda制作)来说,答案如下。基本上,当范围丢失时收集对象时,堆栈将指向实例化帧的行,返回时在该帧中收集对
\uu del\uu
方法中放置了一个断点。当使用del
显式删除对象时,堆栈清楚地表明del
是调用\uuuu del\uuu
的原因
但是,如果由于超出范围/垃圾收集而调用了\uu del\uu
,堆栈会是什么样子?是否很清楚gc
在堆栈上,或者它看起来像执行gc
时代码所在的任何点
或者这在其他方面是非理性的?经过一些基础研究,根据下面的脚本及其附带的输出,至少对CPython(由Anaconda制作)来说,答案如下。基本上,当范围丢失时收集对象时,堆栈将指向实例化帧的行,返回时在该帧中收集对象。也就是说,如果从
afunc
返回后,收集了一个对象,调用帧将位于调用afunc
的点
虽然我无法重现一个示例,但假设发生延迟收集,则\uu del\uu
的调用帧将位于延迟收集发生的点
示例脚本:
import traceback
class ClassWithDel:
def __init__(self, whoami='Default'):
self._whoami = whoami
def __del__(self):
print(f'{self._whoami}: In __del__')
traceback.print_stack()
def whoami(self):
print(f'I am {self._whoami}')
def afunc():
cwd = ClassWithDel()
cwd.whoami()
def closure():
cwd = ClassWithDel()
def closure_with_cwd():
cwd.whoami()
return closure_with_cwd
def afunc_with_closure():
closure_cwd = closure()
closure_cwd()
def afunc_overwrite():
cwd = ClassWithDel()
cwd.whoami()
cwd = ClassWithDel('NotDefault')
cwd.whoami()
def return_list():
results = [ClassWithDel('l1'), ClassWithDel('l2')]
return results
def afunc_overwrite_list():
l = return_list()
l2 = l[1]
l = l2
if __name__ == '__main__':
print('Starting with afunc...')
afunc()
print('\nStarting with closure...')
afunc_with_closure()
print('\nStarting with overwrite...')
afunc_overwrite()
print('\nStarting list overwrite...')
afunc_overwrite_list()
结果是:
$ python -m gc_test
Starting with afunc...
I am Default
Default: In __del__
File ".../lib/python3.8/runpy.py", line 194, in _run_module_as_main
return _run_code(code, main_globals, None,
File ".../lib/python3.8/runpy.py", line 87, in _run_code
exec(code, run_globals)
File "gc_test.py", line 56, in <module>
afunc()
File "gc_test.py", line 11, in __del__
traceback.print_stack()
Starting with closure...
I am Default
Default: In __del__
File ".../lib/python3.8/runpy.py", line 194, in _run_module_as_main
return _run_code(code, main_globals, None,
File ".../lib/python3.8/runpy.py", line 87, in _run_code
exec(code, run_globals)
File "gc_test.py", line 58, in <module>
afunc_with_closure()
File "gc_test.py", line 11, in __del__
traceback.print_stack()
Starting with overwrite...
I am Default
Default: In __del__
File ".../lib/python3.8/runpy.py", line 194, in _run_module_as_main
return _run_code(code, main_globals, None,
File ".../lib/python3.8/runpy.py", line 87, in _run_code
exec(code, run_globals)
File "gc_test.py", line 60, in <module>
afunc_overwrite()
File "gc_test.py", line 39, in afunc_overwrite
cwd = ClassWithDel('NotDefault')
File "gc_test.py", line 11, in __del__
traceback.print_stack()
I am NotDefault
NotDefault: In __del__
File ".../lib/python3.8/runpy.py", line 194, in _run_module_as_main
return _run_code(code, main_globals, None,
File ".../lib/python3.8/runpy.py", line 87, in _run_code
exec(code, run_globals)
File "gc_test.py", line 60, in <module>
afunc_overwrite()
File "gc_test.py", line 11, in __del__
traceback.print_stack()
Starting list overwrite...
l1: In __del__
File ".../lib/python3.8/runpy.py", line 194, in _run_module_as_main
return _run_code(code, main_globals, None,
File ".../lib/python3.8/runpy.py", line 87, in _run_code
exec(code, run_globals)
File "gc_test.py", line 62, in <module>
afunc_overwrite_list()
File "gc_test.py", line 51, in afunc_overwrite_list
l = l2
File "gc_test.py", line 11, in __del__
traceback.print_stack()
l2: In __del__
File ".../lib/python3.8/runpy.py", line 194, in _run_module_as_main
return _run_code(code, main_globals, None,
File ".../lib/python3.8/runpy.py", line 87, in _run_code
exec(code, run_globals)
File "gc_test.py", line 62, in <module>
afunc_overwrite_list()
File "gc_test.py", line 11, in __del__
traceback.print_stack()
$python-mgc\u测试
从afunc开始。。。
我是默认的
默认值:在__
文件“../lib/python3.8/runpy.py”,第194行,在_run_模块_as_main中
返回运行代码(代码、主全局、无、,
文件“../lib/python3.8/runpy.py”,第87行,在运行代码中
exec(代码、运行\全局)
文件“gc_test.py”,第56行,在
afunc()
文件“gc_test.py”,第11行,在__
traceback.print_stack()
从结束开始。。。
我是默认的
默认值:在__
文件“../lib/python3.8/runpy.py”,第194行,在_run_模块_as_main中
返回运行代码(代码、主全局、无、,
文件“../lib/python3.8/runpy.py”,第87行,在运行代码中
exec(代码、运行\全局)
文件“gc_test.py”,第58行,在
带闭包的afunc_()
文件“gc_test.py”,第11行,在__
traceback.print_stack()
从覆盖开始。。。
我是默认的
默认值:在__
文件“../lib/python3.8/runpy.py”,第194行,在_run_模块_as_main中
返回运行代码(代码、主全局、无、,
文件“../lib/python3.8/runpy.py”,第87行,在运行代码中
exec(代码、运行\全局)
文件“gc_test.py”,第60行,在
afunc_overwrite()
文件“gc_test.py”,第39行,afunc_覆盖
cwd=ClassWithDel('NotDefault')
文件“gc_test.py”,第11行,在__
traceback.print_stack()
我不是默认的
非默认值:在__
文件“../lib/python3.8/runpy.py”,第194行,在_run_模块_as_main中
返回运行代码(代码、主全局、无、,
文件“../lib/python3.8/runpy.py”,第87行,在运行代码中
exec(代码、运行\全局)
文件“gc_test.py”,第60行,在
afunc_overwrite()
文件“gc_test.py”,第11行,在__
traceback.print_stack()
开始列表覆盖。。。
l1:在__
文件“../lib/python3.8/runpy.py”,第194行,在_run_模块_as_main中
返回运行代码(代码、主全局、无、,
文件“../lib/python3.8/runpy.py”,第87行,在运行代码中
exec(代码、运行\全局)
文件“gc_test.py”,第62行,在
afunc_覆盖_列表()
afunc覆盖列表中第51行的文件“gc_test.py”
l=l2
文件“gc_test.py”,第11行,在__
traceback.print_stack()
l2:在__
文件“../lib/python3.8/runpy.py”,第194行,在_run_模块_as_main中
返回运行代码(代码、主全局、无、,
文件“../lib/python3.8/runpy.py”,第87行,在运行代码中
exec(代码、运行\全局)
文件“gc_test.py”,第62行,在
afunc_覆盖_列表()
文件“gc_test.py”,第11行,在__
traceback.print_stack()