Доступ к родительским переменным в Python - PullRequest
2 голосов
/ 16 октября 2011

У меня есть что-то вроде этого:

class SomeObject:
    #code to access parents MyVar

class MyClass:
    MyVar = 3

    MyObject = SomeObject()

Мне нужен доступ к MyVar изнутри MyObject. Есть ли способ, которым я могу это сделать?

Спасибо!

Ответы [ 2 ]

5 голосов
/ 16 октября 2011

Вы можете сохранить ссылку на объект MyClass в SomeObject. Вы можете инициализировать ссылку, когда создаете конструктор с объектом MyClass в качестве параметра.

class SomeObject:
    def __init__(self, reference):
         self.reference_=reference
    #code to access parents MyVar
    self.reference_.MyVar=5

class MyClass:
    MyVar = 3

    MyObject = SomeObject(self)

Как указано в unutbu, мой код не работает, поэтому более подробный пример.

class SomeObject:
    def __init__(self):
         self.reference_=None

    def connect(self, reference):
        self.reference_=reference
    #code to access parents MyVar
    def call(self):
        self.reference_.MyVar=5

class MyClass:
    MyVar = 3
    MyObject = SomeObject()
    def connect(self):
        self.MyObject.connect(self)

if __name__ == '__main__':
    myclass = MyClass()
    myclass.connect()
    myclass.MyObject.call()
    print(myclass.MyVar)
0 голосов
/ 16 октября 2011

Вы должны сохранить ссылку на своего родителя, но вы можете сделать так, чтобы это волшебство происходило автоматически:

from weakref import ref

class MyClass(object):
    def __setattr__(self, key, value):
        self.__dict__[key] = value
        try:
            value._parent = ref(self)
        except AttributeError:
            raise TypeError('MyClass cannot have children of type ' +
                            type(value).__name__)
    def __delattr__(self, key):
        v = self.__dict__[key]
        del self.__dict__[key]
        try:
            v._parent = None
        except AttributeError:
            raise TypeError('Child of MyClass is mysteriously '
                            'missing its parent')

class SomeObject(object):
    _parent = None
    @property
    def parent(self):
        if self._parent is not None:
            return self._parent()
        return None

>>> a = MyClass()
>>> a.b = SomeObject()
>>> print a.b.parent
<__main__.MyClass at 0x8ce60f0>
>>> b = a.b
>>> del a.b
>>> print b.parent
None

Переопределяя операторы __setattr__ и __delattr__, вы можете контролировать взгляд ребенка на егородитель и убедитесь, что соединение всегда правильно.Кроме того, это позволяет избежать использования неуклюжих add / remove методов;методы, которые вы можете случайно забыть использовать.Это ограничивает ваши объекты наличием точно одного родителя, но для этих типов моделей это, как правило, желательно.

Наконец, я рекомендую вместо того, чтобы хранить ссылку на родительский объект напрямую,вы держите слабую ссылку.Это позволяет избежать циклических ссылок, которые могут запутать сборщик мусора (a содержит ссылку на b, которая содержит ссылку на a. Их счетчик ссылок никогда не идет в 0, поэтому они несборка мусора).

...