Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python是否垃圾收集在函数范围内不再引用的变量?_Python_Garbage Collection_Cpython - Fatal编程技术网

Python是否垃圾收集在函数范围内不再引用的变量?

Python是否垃圾收集在函数范围内不再引用的变量?,python,garbage-collection,cpython,Python,Garbage Collection,Cpython,在等待长时间运行的函数完成执行时,我开始考虑垃圾收集器是否会清除对不再使用的变量的引用 例如,我有一个函数,如: def long_running_function(): x = MemoryIntensiveObject() print id(x) # lots of hard work done here which does not reference x return 我很好奇解释器是否足够聪明,能够意识到x不再被使用,并且可以取消引用。这有点难测试,因为我可以

在等待长时间运行的函数完成执行时,我开始考虑垃圾收集器是否会清除对不再使用的变量的引用

例如,我有一个函数,如:

def long_running_function():
   x = MemoryIntensiveObject()
   print id(x)
   # lots of hard work done here which does not reference x
   return
我很好奇解释器是否足够聪明,能够意识到x不再被使用,并且可以取消引用。这有点难测试,因为我可以编写代码来检查它的引用计数,但这会隐式地引用它,从而避免了这样做的原因

我的想法是,当解析函数并生成字节码时,它的生成方式可能会允许它在对象不再被引用时清理对象


或者,答案更简单,只要我们仍然在一个“可以”使用它的范围内,它就不会被清除?

不,只要引用该对象的名称仍然在当前范围内定义,CPython就不会垃圾收集该对象

这是因为,即使代码中没有将名称
x
作为文本引用,对
vars()
locals()
的调用仍然可以获取局部名称空间字典的副本(在上次引用
x
之前或之后),因此整个局部名称空间实际上是“根”在执行离开其作用域之前引用的值


我不知道其他实现是如何做到这一点的。特别是,在PyPy、Jython或IronPython等JIT编译的实现中,至少在理论上可以执行这种优化。JVM和CLR JIT实际上在其他语言上执行这种优化。这些平台上的Python是否能够发挥优势完全取决于Python代码编译成的字节码。

您是专门询问CPython还是其他Python实现(例如Jython或PyPy)?答案可能会有所不同。CPython是我最感兴趣的版本,尽管关于替代实现的想法会很有用!(我相应地更新了标记)我怀疑locals()可能起到了一定作用,但您让我思考了JIT编译版本的工作方式以及其他优化的范围。非常感谢。