在Python 2.5中制作一个外观

ari*_*nte 1 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
Run Code Online (Sandbox Code Playgroud)

所以当有人说xxx().x ='hello'时,我希望它在xxx().inner.whatever上设置值而不是xxx().x.

这可能吗?我一直在尝试lambdas,但无济于事.我正在使用Python 2.5

编辑: 现在我的妻子不急于让我睡觉,所以我可以更多地清除代码.我对你们下面的内容有了一些了解,但是从文档来看,你应该避免重写__setattr__/__getattr__并使用属性.如果无法通过属性函数执行此操作,那么我将使用__setattr__/__getattr__?谢谢

Ben*_*nno 6

这是您使用此处记录的__setattr____getattr__方法的地方.

简而言之,如果你这样做:

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)
Run Code Online (Sandbox Code Playgroud)

它应该做你想要的.我强烈建议您阅读与上述相关的文档.

编辑:正如所指出的那样,原始版本因__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)
Run Code Online (Sandbox Code Playgroud)


Ale*_*lli 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)
Run Code Online (Sandbox Code Playgroud)

您不需要self.inner 访问的预防措施,因为__getattr__仅针对不存在的属性调用; 但__setattr__被调用每个属性,所以当你真正需要设置 self.inner(或任何其他属性),你需要明确地绕过__setattr__(在这里我使用object为目的,所以我也继承object- 强烈建议无论如何,在Python 2 .*,否则你会做一个"老式的课程"[[最后在Python 3中消失的那种]],你真的不想...... ;-).