2013-07-11 25 views
3

我发现this recipe创建一个代理类。我用它来包装自定义对象,并且想要重载某些属性并将新属性附加到代理上。然而,当我在代理上调用任何方法时(从代理类中),我最终被委托给了不是我想要的包装。Python对象代理:如何访问代理

有什么方法可以访问或存储对代理的引用吗?

下面是一些代码(未经测试)来演示问题。

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) 

这看ms现在就可以完成这个技巧,但最好直接添加到Proxy类中。

回答

0

你的代码出错的原因是循环__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')()

+0

感谢您的再现和确认,@张扬余。有关如何获得所需行为的任​​何建议? – orange

+0

我已经更新了我的答案。请检查。 @orange – zhangyangyu

+0

我以为我曾尝试过,但我一定犯了一个错误。你的解决方案工作正常在查看代理人的代码之前,我先看看如何修改代理类来查找自己的属性。 – orange