我希望有一个Python类作为另一个Python类的包装器。
像这样的东西
class xxx:
name = property( fset=lambda self, v: setattr(self.inner, 'name', v), fget=lambda self: getattr(self.inner, 'name' ))
def setWrapper( self, obj )
self.inner = obj
所以当有人说xxx()。x ='hello'时,我希望它在xxx()。inner.whatever上设置值而不是xxx()。x。
这可能吗?我一直在尝试lambdas,但无济于事。我正在使用Python 2.5
修改
现在我的妻子不急着让我睡觉,所以我可以更多地清除代码。我对你们下面的内容有了一些了解,但是从docs开始,你应该避免覆盖__setattr__/__getattr__
并使用属性。如果无法通过属性函数执行此操作,那么我将使用__setattr__/__getattr__
?感谢
答案 0 :(得分:6)
您可以使用__setattr__
和__getattr__
方法记录here。
简而言之,如果你这样做:
class Wrapper(object):
def __init__(self, wrapped):
object.__setattr__(self, 'inner', wrapped)
def __getattr__(self, attr):
return getattr(self.inner, attr)
def __setattr__(self, attr, value):
setattr(self.inner, attr, value)
它应该做你想要的。我强烈建议您阅读与上述相关的文档。
编辑:正如所指出的那样,由于无条件地调用__setattr__
,原始版本失败。我已经更新了这个例子。请注意,此版本依赖于新式类行为(如从对象的子类化所示)。对于旧式,我认为你需要弄乱__dict__
如下:
class OldStyleWrapper:
def __init__(self, wrapped):
self.__dict__['inner'] = wrapped
def __getattr__(self, attr):
return getattr(self.inner, attr)
def __setattr__(self, attr, value):
setattr(self.inner, attr, value)
答案 1 :(得分:5)
正如另一个答案所说,__getattr__
和__setattr__
是关键,但在使用后者时需要注意......:
class Wrapper(object):
def __init__(self, wrapped):
object.__setattr__(self, 'inner', wrapped)
def __getattr__(self, n):
return getattr(self.inner, n)
def __setattr__(self, n, value):
setattr(self.inner, n, value)
self.inner
访问您不需要采取预防措施,因为__getattr__
仅针对其他方式不存在的属性进行调用;但__setattr__
会调用每个属性,因此当您确实需要设置 self.inner
(或任何其他属性)时,您需要明确绕过__setattr__
(此处)我正在使用object
用于此目的,所以我也继承来自object
- 高度建议,无论如何,在Python 2. *中,否则你要制作一个“旧式的课程”[[最后在Python 3中消失的那种]],你真的不想......; - )。
答案 2 :(得分:0)
我相信Alex和Ben的答案都应该如下编辑他们的setattr调用:
setattr(self.inner, n, value)