Python对象代理:如何访问代理



我找到了这个创建代理类的方法。我已经用它包装了一个自定义对象,并希望重载某些属性,还将新属性附加到代理。然而,当我调用代理上的任何方法(从代理类中)时,我最终会被委托给wrappee,这不是我想要的。

是否有任何方法可以访问或存储对代理的引用?

这里有一些代码(未经测试)来演示这个问题。

class MyObject(object):
  @property
  def value(self):
    return 42
class MyObjectProxy(Proxy): # see the link above
  def __getattribute__(self, attr):
    # the problem is that `self` refers to the proxied 
    # object and thus this throws an AttributeError. How 
    # can I reference MyObjectProxy.another_value()?
    if attr == 'value':  return self.another_value() # return method or attribute, doesn't matter (same effect)
    return super(MyObjectProxy, self).__getattribute__(attr)
  def another_value(self):
    return 21
o = MyObject()
p = MyObjectProxy(o)
print o.value
print p.value

从某种意义上说,我的问题是代理工作得太好了,它隐藏了自己所有的方法/属性,并将自己伪装成被代理的对象(这是它应该做的)。。。

更新

根据下面的评论,我将__getattribute__更改为:

def __getattribute__(self, attr):
    try:
        return object.__getattribute__(self, attr)
    except AttributeError:
        return super(MyObjectProxy, self).__getattribute__(attr)

目前,这似乎已经达到了目的,但最好将其直接添加到Proxy类中。

代码出错的原因是__getattribute__中的循环。您希望覆盖__getattribute__,以便可以访问代理类本身中的某些属性。但让我们看看。

当您调用p.value时,会调用__getattribute__。然后它来到这里if attr == 'value': return self.another_value()。这里我们需要调用another_value,所以我们再次输入__getattribute__

这次我们来到这里return super(MyObjectProxy, self).__getattribute__(attr)。我们调用Proxy__getattribute__,它尝试在Myobject中获取another_value。因此出现了例外情况。

您可以从回溯中看到,我们最终转到了不应该转到的return super(MyObjectProxy, self).__getattribute__(attr)

Traceback (most recent call last):
  File "proxytest.py", line 22, in <module>
    print p.value
  File "proxytest.py", line 13, in __getattribute__
    if attr == 'value':  return self.another_value() # return method or attribute, doesn't matter (same effect)
  File "proxytest.py", line 14, in __getattribute__
    return super(MyObjectProxy, self).__getattribute__(attr)
  File "/home/hugh/m/tspace/proxy.py", line 10, in __getattribute__
    return getattr(object.__getattribute__(self, "_obj"), name)
AttributeError: 'MyObject' object has no attribute 'another_value'

编辑:
将代码if attr == 'value': return self.another_value()的行更改为if attr == 'value': return object.__getattribute__(self, 'another_value')()

最新更新