【问题标题】:Python object proxying: how to access proxyPython对象代理:如何访问代理
【发布时间】:2013-07-11 02:40:00
【问题描述】:

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

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

更新

根据下面的cmets,我把__getattribute__改成了这个:

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

现在这似乎可以解决问题,但最好将其直接添加到 Proxy 类中。

【问题讨论】:

    标签: python proxy-classes


    【解决方案1】:

    您的代码出错的原因是__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。所以会出现异常。

    你可以从 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')()

    【讨论】:

    • 感谢@zhangyangyu以上转载和确认。有关如何获得所需行为的任​​何建议?
    • 我以为我以前尝试过,但我一定犯了一个错误。您的解决方案运行良好。我将看看修复 proxy 类以在访问代理之前先查找它自己的属性。
    • 直接修复Proxy 类似乎比我想象的要大。我试图在__getattribute__中调用hasattr(self, attr),但这似乎以无限循环结束(hasattr真的在调用__getattribute吗?)
    • 是的。阅读here.@orange
    • 讨厌!我用你的答案和我在你链接的帖子中发现的内容更新了我的问题。
    猜你喜欢
    • 2012-03-30
    • 2021-06-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多