python 中的 locals() 和对象引用
locals() and object reference in python
我对 python 如何跟踪 locals()
中的对象感到好奇。
考虑以下脚本:
import gc
class T(object):
pass
def func1():
t = T()
#locals()
del t
#locals()
for o in gc.get_objects():
if type(o) is T:
print("STILL EXISTS")
func1()
运行 两个 locals()
调用评论(如上)没有给我任何消息,表明创建的 T()
对象被垃圾收集。
当我使用第一个 locals()
命令 运行 它(删除第一个注释)时,它似乎创建了一个字典,其中包含对我的 t
对象的引用。该字典未与任何名称相关联,因此我不希望该字典在没有被垃圾收集的情况下继续存在。
问题是,运行宁代码,我得到 "STILL EXISTS"
。即使我从函数命名空间中删除 t
,该对象也不会被垃圾回收,因为 locals()
返回的字典仍在引用它。
有趣的是,如果我再次调用 locals()
(删除上面代码中的第二条注释),那么字典会以某种方式更新,它不包含 t
,对象是垃圾收集成功(我没有收到 "STILL EXISTS"
消息)。
我觉得这个行为有点奇怪。
问题是:
locals()
返回的字典很长正常吗
活过,甚至没有将它与任何名字联系起来?
- 从当前范围删除名称时,此词典不会自动更新是正常的还是有任何原因?
编辑:我正在使用 cpython 3.6
谢谢!
locals()
很奇怪。在函数内部,每个 locals()
调用都会将当前局部变量值复制到与堆栈帧关联的字典中,并 returns 字典中。 dict not 用于实际的局部变量查找,但它 是 附加到 frame 对象,并且它不是每次都是新的 dict;同一个堆栈帧中的所有 locals()
个调用重用同一个字典。
当您调用 locals()
时,locals dict 现在具有对当前由局部变量引用的所有对象的引用。这将使这些对象保持活动状态,直到堆栈帧死亡,或者在该堆栈帧内使用不同的局部变量值进行新的 locals()
调用。其他一些事情也会更新局部字典,例如检索堆栈帧对象的 f_locals
属性,但局部变量赋值不会自行更新局部字典。
我对 python 如何跟踪 locals()
中的对象感到好奇。
考虑以下脚本:
import gc
class T(object):
pass
def func1():
t = T()
#locals()
del t
#locals()
for o in gc.get_objects():
if type(o) is T:
print("STILL EXISTS")
func1()
运行 两个 locals()
调用评论(如上)没有给我任何消息,表明创建的 T()
对象被垃圾收集。
当我使用第一个 locals()
命令 运行 它(删除第一个注释)时,它似乎创建了一个字典,其中包含对我的 t
对象的引用。该字典未与任何名称相关联,因此我不希望该字典在没有被垃圾收集的情况下继续存在。
问题是,运行宁代码,我得到 "STILL EXISTS"
。即使我从函数命名空间中删除 t
,该对象也不会被垃圾回收,因为 locals()
返回的字典仍在引用它。
有趣的是,如果我再次调用 locals()
(删除上面代码中的第二条注释),那么字典会以某种方式更新,它不包含 t
,对象是垃圾收集成功(我没有收到 "STILL EXISTS"
消息)。
我觉得这个行为有点奇怪。
问题是:
locals()
返回的字典很长正常吗 活过,甚至没有将它与任何名字联系起来?- 从当前范围删除名称时,此词典不会自动更新是正常的还是有任何原因?
编辑:我正在使用 cpython 3.6
谢谢!
locals()
很奇怪。在函数内部,每个 locals()
调用都会将当前局部变量值复制到与堆栈帧关联的字典中,并 returns 字典中。 dict not 用于实际的局部变量查找,但它 是 附加到 frame 对象,并且它不是每次都是新的 dict;同一个堆栈帧中的所有 locals()
个调用重用同一个字典。
当您调用 locals()
时,locals dict 现在具有对当前由局部变量引用的所有对象的引用。这将使这些对象保持活动状态,直到堆栈帧死亡,或者在该堆栈帧内使用不同的局部变量值进行新的 locals()
调用。其他一些事情也会更新局部字典,例如检索堆栈帧对象的 f_locals
属性,但局部变量赋值不会自行更新局部字典。