在Python 2.5中制作一个外观

时间:2009-09-24 03:07:02

标签: python

我希望有一个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__?感谢

3 个答案:

答案 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)