【发布时间】:2016-11-25 03:25:04
【问题描述】:
我正在编写一个函数,它需要一个巨大的参数,并且运行了很长时间。它只需要中途论证。如果没有更多的引用,函数有没有办法删除参数指向的值?
我可以在函数返回后立即将其删除,如下所示:
def f(m):
print 'S1'
m = None
#__import__('gc').collect() # Uncommenting this doesn't help.
print 'S2'
class M(object):
def __del__(self):
print '__del__'
f(M())
打印出来:
S1
S2
__del__
我需要:
S1
__del__
S2
我也尝试过def f(*args): 和def f(**kwargs),但没有帮助,我最后还是得到了__del__。
请注意,我的代码依赖于 Python 具有引用计数这一事实,并且一旦对象的引用计数降至零,__del__ 就会被调用。我希望函数参数的引用计数在函数中间降为零。这可能吗?
请注意,我知道一种解决方法:传递参数列表:
def f(ms):
print 'S1'
del ms[:]
print 'S2'
class M(object):
def __del__(self):
print '__del__'
f([M()])
打印出来:
S1
__del__
S2
有没有办法在不更改 API 的情况下提前删除(例如,将列表引入参数)?
如果很难获得适用于许多 Python 实现的可移植解决方案,我需要一些适用于最新 CPython 2.7 的解决方案。不必记录在案。
【问题讨论】:
-
你为什么要这样做?一般来说,我认为 python 不会在引用计数达到 0 时立即进行垃圾收集,但只会在一段时间后(未定义)。您应该能够强制进行垃圾回收。
-
参数是从调用者的作用域传入的。最终该对象仍然在那里被引用。无论您将函数中的引用计数降低多少,直到您的函数结束,该对象可能都不会被垃圾收集,因为尚未清理父范围的引用。 – 这在很大程度上只是一个猜测,我不知道
foo(m)和foo(M())之间的行为会有什么不同;逻辑规定它不应该不同,但这也取决于实现。 -
我想说,即使你取消绑定参数,它仍然存在于函数范围之外。
-
最后你不应该依赖 Python 的内部来进行内存管理。尽量减少内存消耗的最佳方法是以不同的方式解决问题,并以保证使用更少内存的方式实现它;例如通过从磁盘等读取流。
-
你永远无法知道何时或指望
__del__()被调用,除非你自己明确地这样做。 Python 不是 C++。
标签: python python-2.7 destructor reference-counting