3

我找到了这个配方来创建一个代理类。我用它来包装一个自定义对象,并希望重载某些属性并将新属性附加到代理。但是,当我调用代理上的任何方法时(从代理类中),我最终被委派给了我不想要的 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类中。

4

1 回答 1

1

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

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

这次我们来了return super(MyObjectProxy, self).__getattribute__(attr)。我们调用Proxy's __getattribute__,它会尝试获取another_value. Myobject所以会出现异常。

从 traceback 可以看出,我们最终去了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')().

于 2013-07-11T04:01:39.577 回答