弱点和绑定方法 [英] weakrefs and bound methods

查看:72
本文介绍了弱点和绑定方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

嗨。


我有一个弱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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆