嵌套对象与setattr和getattr(没错,到了这个时候)

6 投票
1 回答
4994 浏览
提问于 2025-04-17 12:31

概述:

class Inner(object):
    def __init__(self, x):
        self.x = x

class Outer(object):
    def __init__(self, z):
        self.inner = Inner(z)

o = Outer(10)

现在,我希望这个外部对象的行为是透明的——也就是说,任何在 o 上设置的属性都应该自动设置到 o.inner 上;同样地,读取属性时,o.something 实际上应该返回 o.inner.something 的值。这有点像一个代理或者中继。

对于 Outer 来说,__getattr__ 的实现看起来很简单,而且能正常工作:

def __getattr__(self, item):
    return getattr(self, item)

那么我该如何处理 __setattr__ 呢?我想不出任何不会导致递归错误的办法,这让我很沮丧。

或者说这个概念本身就有问题吗?

(我尝试的另一种方法是让 Outer 继承自 Inner——但这样在视觉上并不太好,尤其是 @classmethods 的表现也不理想,更不用说IDE在这些里面会迷失,无法解析某些属性。我们先不讨论这个吧,可能以后再说?)

1 个回答

7

这里的关键在于如何正确设置Outer类的inner属性。你可以调用Outer的基类object__setattribute__方法来实现:

class Inner(object):
    def __init__(self, x):
        self.x = x

class Outer(object):    
    def __init__(self, z):
        object.__setattr__(self, 'inner', Inner(z))

    def __getattr__(self, name):
        return getattr(self.inner, name)

    def __setattr__(self, name, value):
        return setattr(self.inner, name, value)

现在,这样就能正常工作了:

o = Outer(10)
print o.x        # 10
print o.inner.x  # 10
o.g = 3
print o.g        # 3
print o.inner.g  # 3

不过,我不太明白为什么在这种情况下不想使用继承。让Outer继承自Inner似乎更自然,也更符合Python的风格。

撰写回答