Вложенные объекты и setattr & getattr (да, это то время)

описание:

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.sommething. Что-то вроде прокси или ретранслятора.

__getattr__ на Outer кажется простым и работает:

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

как бы я ручки __setattr__? Я не мог придумать ничего, что не вызвало бы ошибку рекурсии и не заставило бы меня ненавидеть себя.

или сама концепция несовершенна?

(другой подход, который я пытался сделать Outer подкласс Inner -- это на самом деле не играло эстетически настоящее@classmethods, не говоря уже о том, что IDE потеряется внутри них - не сможет разрешить некоторые атрибуты. Может, оставим это пока?)

1 ответов


хитрая часть устанавливает на Outer правильно класс. Что вы можете сделать, это вызвать __setattribute__ метод object (базовый класс Outer):

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

однако мне непонятно, почему вы не хотите использовать наследование в этом случае. Она кажется более естественной и подходящие для Python, чтобы иметь Outer наследовать от Inner.