弱点和绑定方法 [英] weakrefs and bound methods
问题描述
嗨。
我有一个弱refs和绑定方法的问题。
问题的最佳解释是一小段代码。我有三个类Wrapper,Foo和Bar:
import weakref
class Wrapper(object):
def __init __(self,x):
self.x = weakref.ref(x)
def __call __(self,* args,** kwargs ):
x = self.x()
如果x为无,则为
:
print" lost reference"
:否则:
返回x(* args,** kwargs)
class Foo(对象):
def __init __(自我):
self._methods = set()
self._methods.add(Wrapper(self._foo))
def _foo(self):
print" _foo"
def callMethods(self):
for self in self ._methods:
方法()
def __del __(自我):
print" del Foo"
class Bar(对象):
def __init __(自我):
self._methods = set()
self._methods.add(self._foo)
def _foo(self):
print" _foo"
def callMethods(self):
for self._methods中的方法:
方法()
def __del __(self):
print" del Bar"
现在看看我这样做会发生什么:
>> f = Foo()
f.callMethods()
丢失参考
> ;> del f
del Foo
>> b = Bar()
b.callMethods()
_foo
>> del b
Foo丢失了对其方法的引用,但另一方面Bar有一个refloop并且
永远不会被删除。
有谁知道这里发生了什么?如何在没有refloop和
的情况下编写这样的类而不会丢失引用?
我正在使用:
Python 2.5。 1(r251:54863,2007年5月2日,16:56:35)
[GCC 4.1.2(Ubuntu 4.1.2-0ubuntu4)] on linux2
-panzi
解决方案
当我将类Wrapper更改为以下时,Foo类起作用:
class Wrapper(object):
def __init __(self,x):
self.func_name = x.func_name
self.x = weakref.ref(x.im_self)
def __call __(self,* args,** kwargs):
x = self.x()
如果x为None:
print" lost reference"
else:
return getattr(x,self.func_name )(* args,** kwargs)
但这很难看。有什么好主意吗?
On Sun,2007年10月7日16:51:33 +0200,Mathias Panzenboeck写道:
import weakref
class Wrapper(object):
def __init __(self,x):
self.x = weakref.ref(x)
def __call __(self,* args,** kwargs):
x = self.x()
如果x为无,则为
:
print" lost reference"
else:
return x(* args,** kwargs )
类Foo(对象):
def __init __(自我):
self._methods = set()
self._methods.add(Wrapper(self._foo))
def _foo(self):
print" _foo"
def callMethods(self):
for self._methods中的方法:
方法()
def __del __(自我):
print" del Foo"
class Bar(对象):
def __init __(self):
self._method s = set()
self._methods.add(self._foo)
def _foo(个体经营):
打印_foo
def callMethods(self):
for self._methods中的方法:
method()
def __del __(自我):
print" del Bar"
>>> f = Foo()
f.callMethods()
丢失参考
>>> del f
del Foo
>>> ; b = Bar()
b.callMethods()
_foo
>>> del b
Foo丢失了对其方法的引用,但另一方面Bar有一个refloop并且
永远不会被删除。
``del b``只删除名称`b`。它不会删除对象。
在交互式解释器中仍然有一个名称`_`绑定它。
`_`保持绑定到最后一个非-`None`导致翻译。
删除所有`__del __()`方法,因为它们阻止垃圾收集器
收集循环 。
Ciao,
Marc''BlackJack''Rintsch
10月7日,12日:26 pm,Marc''BlackJack''Rintsch< bj _... @ gmx.netwrote:
删除所有那些`__del __()`方法,因为它们阻止垃圾收集器
来自收集周期。
我完全同意并且我会补充说__del__方法总是
一个坏主意。另请注意,最近Raymond Hetting在
这个列表中说他想提交一个PEP来删除__ $ _ $
Python 3000(我不知道这是否会永远发生艰难的事情。
Michele Simionato
Hi.
I have a problem with weak refs and bound methods. The best explanation for the
problem is a short bit of code. I have the three classes Wrapper, Foo and Bar:
import weakref
class Wrapper(object):
def __init__(self,x):
self.x = weakref.ref(x)
def __call__(self,*args,**kwargs):
x = self.x()
if x is None:
print "lost reference"
else:
return x(*args,**kwargs)
class Foo(object):
def __init__(self):
self._methods = set()
self._methods.add(Wrapper(self._foo))
def _foo(self):
print "_foo"
def callMethods(self):
for method in self._methods:
method()
def __del__(self):
print "del Foo"
class Bar(object):
def __init__(self):
self._methods = set()
self._methods.add(self._foo)
def _foo(self):
print "_foo"
def callMethods(self):
for method in self._methods:
method()
def __del__(self):
print "del Bar"
Now look what happens when I do this:
>>f=Foo()
f.callMethods()
lost reference
>>del f
del Foo
>>b=Bar()
b.callMethods()
_foo
>>del b
Foo looses the reference to its method but Bar on the other hand has a refloop and
never gets deleted.
Does anyone know what happens here? How can I write such classes without refloop and
without lost reference?
I''m using:
Python 2.5.1 (r251:54863, May 2 2007, 16:56:35)
[GCC 4.1.2 (Ubuntu 4.1.2-0ubuntu4)] on linux2
-panzi解决方案When I change the class Wrapper to following, the class Foo works:
class Wrapper(object):
def __init__(self,x):
self.func_name = x.func_name
self.x = weakref.ref(x.im_self)
def __call__(self,*args,**kwargs):
x = self.x()
if x is None:
print "lost reference"
else:
return getattr(x,self.func_name)(*args,**kwargs)
But that''s ugly. Any better idea?
On Sun, 07 Oct 2007 16:51:33 +0200, Mathias Panzenboeck wrote:
import weakref
class Wrapper(object):
def __init__(self,x):
self.x = weakref.ref(x)
def __call__(self,*args,**kwargs):
x = self.x()
if x is None:
print "lost reference"
else:
return x(*args,**kwargs)
class Foo(object):
def __init__(self):
self._methods = set()
self._methods.add(Wrapper(self._foo))
def _foo(self):
print "_foo"
def callMethods(self):
for method in self._methods:
method()
def __del__(self):
print "del Foo"
class Bar(object):
def __init__(self):
self._methods = set()
self._methods.add(self._foo)
def _foo(self):
print "_foo"
def callMethods(self):
for method in self._methods:
method()
def __del__(self):
print "del Bar"
Now look what happens when I do this:
>>>f=Foo()
f.callMethods()
lost reference
>>>del f
del Foo
>>>b=Bar()
b.callMethods()
_foo
>>>del b
Foo looses the reference to its method but Bar on the other hand has a refloop and
never gets deleted.``del b`` just deletes the name `b`. It does not delete the object.
There''s still the name `_` bound to it in the interactive interpreter.
`_` stays bound to the last non-`None` result in the interpreter.
Drop all those `__del__()` methods as they prevent the garbage collector
from collecting "cycles".
Ciao,
Marc ''BlackJack'' Rintsch
On Oct 7, 12:26 pm, Marc ''BlackJack'' Rintsch <bj_...@gmx.netwrote:
Drop all those `__del__()` methods as they prevent the garbage collector
from collecting "cycles".I fully agree and I will add that __del__ methods are always
a bad idea. Also notice that recently Raymond Hetting said in
this list that he wanted to submit a PEP to remove __del__ from
Python 3000 (I don''t know if this will ever happen tough).
Michele Simionato
这篇关于弱点和绑定方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!