Python:取消引用弱代理 [英] Python: dereferencing weakproxy
问题描述
有没有办法从指向它的弱代理中获取原始对象?例如,是否与 weakref.proxy()
相反?
导入弱引用C类(对象):def __init__(self, other):self.other = weakref.proxy(other)类其他(对象):经过其他 = [Other() for i in xrange(3)]my_list = [C(others[i % len(others)]) for i in xrange(10)]
我需要从 my_list
获取唯一的 other
成员列表.我喜欢这样的任务的方式是使用 set
:
unique_others = {x.other for x in my_list}
不幸的是,这会抛出 TypeError: unhashable type: 'weakproxy'
unique_others = []对于 my_list 中的 x:如果 x.other 在 unique_others 中:继续unique_others.append(x.other)
但标题中指出的一般问题仍然存在.如果我只控制了my_list
,而others
被埋在某个lib中,有人可以随时删除它们,我想通过收集来防止删除怎么办列表中的非弱 引用?
repr()
,而不是
我想应该有类似 weakref.unproxy
我不知道的东西.基本上有类似 weakref.unproxy
的东西,但它只是命名为 weakref.ref(x)()
代码>.代理对象仅用于委托,并且实现相当不稳定......
==
函数无法正常工作:
但是,我发现您不想一直调用 weakref.ref
对象.具有取消引用支持的良好工作代理会很好.
但目前,这是不可能的.如果你查看你看到的 python 内置源代码,你需要类似 PyWeakref_GetObject,但是根本没有调用此方法(并且:如果参数错误,它会引发 PyErr_BadInternalCall
,因此它似乎是一个内部函数).PyWeakref_GET_OBJECT用的比较多,但是weakref.py 可以做到这一点.
所以,很抱歉让您失望,但是您weakref.proxy
并不是大多数人想要的用例.但是,您可以制作自己的代理
实现.这并不难.只需在内部使用 weakref.ref
并覆盖 __getattr__
、__repr__
等
关于 PyCharm 如何能够产生正常的 repr
输出的一点旁注(因为你在评论中提到了这一点):
如您所见,调用原始的 __repr__
真的很有帮助!
Is there any way to get the original object from a weakproxy pointed to it? eg is there the inverse to weakref.proxy()
?
import weakref
class C(object):
def __init__(self, other):
self.other = weakref.proxy(other)
class Other(object):
pass
others = [Other() for i in xrange(3)]
my_list = [C(others[i % len(others)]) for i in xrange(10)]
I need to get the list of unique other
members from my_list
. The way I prefer for such tasks
is to use set
:
unique_others = {x.other for x in my_list}
Unfortunately this throws TypeError: unhashable type: 'weakproxy'
unique_others = []
for x in my_list:
if x.other in unique_others:
continue
unique_others.append(x.other)
but the general problem noted in the caption is still active.
What if I have only my_list
under control and others
are burried in some lib and someone may delete them at any time, and I want to prevent the deletion by collecting nonweak refs in a list?
repr()
of the object itself, not <weakproxy at xx to Other at xx>
I guess there should be something like weakref.unproxy
I'm not aware about.Basically there is something like weakref.unproxy
, but it's just named weakref.ref(x)()
.
The proxy object is only there for delegation and the implementation is rather shaky...
The ==
function doesn't work as you would expect it:
>>> weakref.proxy(object) == object
False
>>> weakref.proxy(object) == weakref.proxy(object)
True
>>> weakref.proxy(object).__eq__(object)
True
However, I see that you don't want to call weakref.ref
objects all the time. A good working proxy with dereference support would be nice.
But at the moment, this is just not possible. If you look into python builtin source code you see, that you need something like PyWeakref_GetObject, but there is just no call to this method at all (And: it raises a PyErr_BadInternalCall
if the argument is wrong, so it seems to be an internal function). PyWeakref_GET_OBJECT is used much more, but there is no method in weakref.py that could be able to do that.
So, sorry to disappoint you, but you weakref.proxy
is just not what most people would want for their use cases. You can however make your own proxy
implementation. It isn't to hard. Just use weakref.ref
internally and override __getattr__
, __repr__
, etc.
On a little sidenote on how PyCharm is able to produce the normal repr
output (Because you mentioned that in a comment):
>>> class A(): pass
>>> a = A()
>>> weakref.proxy(a)
<weakproxy at 0x7fcf7885d470 to A at 0x1410990>
>>> weakref.proxy(a).__repr__()
'<__main__.A object at 0x1410990>'
>>> type( weakref.proxy(a))
<type 'weakproxy'>
As you can see, calling the original __repr__
can really help!
这篇关于Python:取消引用弱代理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!