python中的locals()和对象引用

时间:2018-09-14 18:18:11

标签: python garbage-collection cpython

我对python如何跟踪@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Button work = (Button) findViewById(R.id.button1); work.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { for (int s = 0; s < 4; s++) { Toast.makeText(getApplicationContext(), "This is my Toast message!", Toast.LENGTH_SHORT).show(); } } }); } 中的对象感到好奇。

考虑以下脚本:

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消息)。

我发现这种行为有点奇怪。

问题是:

  1. "STILL EXISTS"返回的字典很长是否正常? 活着,即使没有与任何名字相关联?
  2. 这是正常现象吗,还是有任何原因导致从当前作用域删除名称时该词典没有自动更新?

编辑:我正在使用cpython 3.6

谢谢!

1 个答案:

答案 0 :(得分:3)

locals()很奇怪。在函数内部,每个locals()调用都会将当前局部变量值复制到与堆栈框架关联的字典中,并返回该字典。该dict是用于实际的局部变量查找,但它是 附加到框架对象,并且并非每次都是新的dict。同一堆栈帧中的所有locals()调用都重复使用相同的字典。

当您调用locals()时,locals dict现在可以引用当前由局部变量引用的所有对象。这将使这些对象保持活动状态,直到堆栈框架死亡,或在具有不同局部变量值的堆栈框架内进行新的locals()调用为止。其他一些事情也将更新locals dict,例如检索堆栈框架对象的f_locals属性,但是局部变量赋值不会单独更新locals dict。