有什么方法可以从弱代理中获取原始对象吗?例如,weakref.proxy()
是否有反函数?
一个简化的例子(python2.7):
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)]
我需要从
other
获得唯一的my_list
成员的列表。我喜欢此类任务的方式是使用
set
:unique_others = {x.other for x in my_list}
不幸的是,这引发了
TypeError: unhashable type: 'weakproxy'
我设法以命令式的方式解决了特定的问题(缓慢而肮脏):unique_others = []
for x in my_list:
if x.other in unique_others:
continue
unique_others.append(x.other)
但是标题中指出的一般问题仍然有效。
如果我只控制
my_list
和others
到某个库中,并且有人可以随时删除它们,又想通过在列表中收集 nonweak 引用来防止删除,该怎么办?或者我可能想获取对象本身的
repr()
,而不是<weakproxy at xx to Other at xx>
我猜应该有我不知道的类似weakref.unproxy
的东西。 最佳答案
基本上有类似weakref.unproxy
的东西,但它只是命名为weakref.ref(x)()
。
代理对象仅用于委派,实现相当不稳定。==
函数无法正常运行:
>>> weakref.proxy(object) == object
False
>>> weakref.proxy(object) == weakref.proxy(object)
True
>>> weakref.proxy(object).__eq__(object)
True
但是,我看到您不想一直调用
weakref.ref
对象。一个具有解除引用支持的良好工作代理将是不错的选择。但是目前,这是不可能的。如果您查看python内置的源代码,则需要像PyWeakref_GetObject这样的东西,但根本没有对该方法的调用(并且:如果参数错误,它将引发一个
PyErr_BadInternalCall
,因此它似乎是一个内部函数)。 PyWeakref_GET_OBJECT的使用更多,但是weakref.py中没有能够做到这一点的方法。因此,很抱歉让您失望,但是
weakref.proxy
并不是大多数人想要的用例。但是,您可以创建自己的proxy
实现。这并不难。只需在内部使用weakref.ref
并覆盖__getattr__
,__repr__
等即可。关于PyCharm如何能够产生正常的
repr
输出的一点说明(因为您在注释中提到了这一点):>>> 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'>
如您所见,调用原始的
__repr__
确实有帮助!