有人可以解释为什么以下代码的行为方式如下:
import types
class Dummy():
def __init__(self, name):
self.name = name
def __del__(self):
print "delete",self.name
d1 = Dummy("d1")
del d1
d1 = None
print "after d1"
d2 = Dummy("d2")
def func(self):
print "func called"
d2.func = types.MethodType(func, d2)
d2.func()
del d2
d2 = None
print "after d2"
d3 = Dummy("d3")
def func(self):
print "func called"
d3.func = types.MethodType(func, d3)
d3.func()
d3.func = None
del d3
d3 = None
print "after d3"
Run Code Online (Sandbox Code Playgroud)
输出(注意d2的析构函数从不被调用)是这个(python 2.7)
delete d1
after d1
func called
after …Run Code Online (Sandbox Code Playgroud) 是否有任何障碍阻止weakref做一切__del__但有更强保证的事情(例如,finalize保证在解释器退出之前进行呼叫,并且呼叫的顺序是明确定义的等等)?
看来,在遥远的过去,人们认为这weakref将最终导致去除__del__从语言.
什么阻止了这种情况发生?
似乎很少有用例__del__,而且我所知道的所有用例似乎至少与weakref回调或(或通常更好)一起使用回调或weakref.finalize.
更新:
随着PEP 442显着改善了@gz和@ user2357112所提__del__及的行为和问题weakref,我想知道这种语言是否通常朝着__del__更可靠的方向发展,或者转向使用weakref而不是__del__两者兼有.
python garbage-collection destructor weak-references python-3.x
我阅读不同的方式来清理对象在Python中,我已经对这些问题跌跌撞撞(1,2)基本上说,清理使用__del__()是不可靠的,下面的代码应避免:
def __init__(self):
rc.open()
def __del__(self):
rc.close()
Run Code Online (Sandbox Code Playgroud)
问题是,我正在使用这个代码,我无法重现上述问题中引用的任何问题.据我所知,我不能用with声明来替代,因为我为闭源软件提供了一个Python模块(testIDEA,任何人?)这个软件将创建特定类的实例并处理它们,这些实例必须准备好在两者之间提供服务.__del__()我看到的唯一替代方法是手动调用open()并close()根据需要,我认为这将非常容易出错.
我明白,当我关闭解释器时,不能保证我的对象会被正确销毁(并且它不会打扰我,哎呀,即使是Python作者也认为它没问题).除此之外,我是否通过__del__()清理来玩火?
PS:我最初想在meta上发布一个关于无法复制的错误问题的咆哮,但意识到我不会得到我需要的技术细节.
我了解到,蟒蛇并 没有 保证的是__del__当一个对象被删除时调用.换句话说,del x 并不一定调用析构函数x.__del__().
如果我想确保正确的对象清理,我应该使用上下文管理器(在with语句中).
我知道这很愚蠢,但出于几个原因(请不要问为什么)我与Python 2.4绑定了系统; 因此上下文管理器是不可能的(它们是在Python 2.5中引入的)
所以我需要一个替代解决方案,因此我的问题是:是否有可以帮助我__del__可靠使用的最佳实践?我正在思考"如果python提供这样的功能,必须有一种方法可以有效地使用它(我只是愚蠢地弄清楚如何)",,,
或者我只是天真,应该忘记__del__并继续采用完全不同的方法?