简体   繁体   English

python中的locals()和对象引用

[英]locals() and object reference in python

I found something curious about how python tracks objects in locals() . 我发现了一些关于python如何跟踪locals()对象的好奇心。

Considering the following script: 考虑以下脚本:

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()

Running with both locals() calls commented (as above) gives me no messages, indicated that the T() object created was garbage collected. 运行两个locals()调用注释(如上所示)没有给我任何消息,表明创建的T()对象是垃圾回收。

When I run it with the first locals() command (removing the first comment), it seems to create a dictionary that contains a reference to my t object. 当我使用第一个locals()命令(删除第一个注释)运行它时,它似乎创建了一个包含对我的t对象的引用的字典。 This dictionary is not associated to any names, so I wouldn't expect this dict to live as without being garbage collected. 这个字典没有与任何名字相关联,所以我不希望这个字典在没有被垃圾收集的情况下存活。

The problem is that, running the code, I get "STILL EXISTS" . 问题是,运行代码,我得到"STILL EXISTS" Even if I delete t from the function namespace, the object is not garbage collected as the dict returned by locals() is still referring to it. 即使我从函数名称空间中删除了t ,该对象也不会被垃圾收集,因为locals()返回的dict仍在引用它。

Funny enough, if I call locals() again (removing the second comment in the code above), then somehow the dictionary gets updated, it does not contain t in it and the object is garbage collected successfully (and I don't get an "STILL EXISTS" message). 有趣的是,如果我再次调用locals() (删除上面代码中的第二个注释),那么字典会以某种方式更新,它不包含t并且对象被垃圾收集成功(并且我没有得到"STILL EXISTS"消息)。

I find this behaviour a bit weird. 我发现这种行为有点奇怪。

Questions are: 问题是:

  1. Is it normal that the dictionary returned by locals() is long lived, even without associating it with any names? 即使没有将它与任何名称相关联, locals()返回的字典是否很长,这是正常的吗?
  2. Is it normal or is there any reason that this dictionary does not get updated automatically when deleting names from the current scope? 这是正常的还是有任何理由在从当前范围中删除名称时这个字典没有自动更新?

Edit: I am using cpython 3.6 编辑:我正在使用cpython 3.6

Thanks! 谢谢!

locals() is weird. locals()很奇怪。 Inside a function, every locals() call copies the current local variable values into a dict associated with the stack frame and returns the dict. 在函数内部,每个locals()调用将当前局部变量值复制到与堆栈帧相关联的dict中并返回dict。 The dict is not used for actual local variable lookup, but it is attached to the frame object, and it is not a new dict every time; 该字典用于实际的本地变量查找,但是连接到框架对象,每一次它不是一个新的字典; all locals() calls in the same stack frame reuse the same dict. 所有locals()调用在同一堆栈帧中重用相同的dict。

When you call locals() , the locals dict now has a reference to all objects currently referred to by local variables. 当你调用locals() ,locals dict现在引用当前变量当前引用的所有对象。 This will keep those objects alive until either the stack frame dies, or a new locals() call is made inside that stack frame with different local variable values. 这将使这些对象保持活动状态,直到堆栈帧死亡,或者在具有不同局部变量值的堆栈帧内进行新的locals()调用。 A few other things will also update the locals dict, such as retrieving the f_locals attribute of the stack frame object, but local variable assignment does not update the locals dict by itself. 还有一些其他的东西也会更新locals dict,比如检索堆栈帧对象的f_locals属性,但局部变量赋值不会自动更新locals dict。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM