【发布时间】:2021-12-12 05:58:00
【问题描述】:
我有以下功能:
def myfn():
big_obj = BigObj()
result = consume(big_obj)
return result
BigObj() 值的引用计数何时增加/减少: 是吗:
- 当
consume(big_obj)被调用时(因为之后在 myfn 中没有引用 big_obj) - 函数返回时
- 有点,我还没有
将最后一行更改为:
return consume(big_obj)
编辑(对 cmets 的说明):
- 在函数返回之前存在局部变量
- 可以使用 del obj 删除引用
但是临时变量是什么(例如 f1(f2())?
我用这段代码检查了对临时对象的引用:
import sys
def f2(c):
print("f2: References to c", sys.getrefcount(c))
def f0():
print("f0")
f2(object())
def f1():
c = object()
print("f1: References to c", sys.getrefcount(c))
f2(c)
f0()
f1()
打印出来:
f0
f2: References to c 3
f1: References to c 2
f2: References to c 4
看来,对临时变量的引用被保留了。并不是说 getrefcount 提供的信息比您预期的要多,因为它也包含一个引用。
【问题讨论】:
-
变量
big_obj在函数返回之前仍然存在,即使没有更多的代码行可以访问它。要影响它的生命周期,你唯一能做的就是del big_obj,但如果函数无论如何都将要返回,那么这样做是没有意义的。 (如果要在函数中执行进一步的内存密集型操作,这可能非常有用,但不再需要big_obj。) -
是否有可能调用
consume(big_obj),以便删除myfn中的引用并保留consumefn 中的引用。所以基本上类似于 C++ 中的移动操作? -
你需要这个做什么?
-
我有一个懒惰的 SingleLinkedList。大致如下:
(value, next_fn)列表的下一项是一个函数,当第一次访问下一项时会调用该函数。下一项替换为 next_fn 的返回值,即另一个(value, next_fn)或None。所以big_obj持有对列表头部的引用,只要引用了 big_obj,所有生成的项目也都保存在内存中...... -
试试
consume(BigObj())?无论如何,这一切都将依赖于实现细节,没有语言保证当对象的引用计数达到零时会立即回收(尽管在 CPython 中是这样)
标签: python local-variables reference-counting