Подтвердить что ты не робот

Общий доступ к объектам Python

У меня есть класс, который отслеживает несколько других классов. Каждому из этих других классов необходимо получить доступ к значению конкретной переменной, и любой из этих других классов также должен иметь возможность модифицировать эту конкретную переменную, чтобы все другие классы могли видеть измененную переменную.

Я попытался выполнить это с помощью свойств. Пример следующий:

class A:
    def __init__(self, state):
        self._b_obj = B(self)
        self._state = state

    @property
    def state(self):
        return self._state

    @state.setter
    def state(self,val):
        self._state = val

    @property
    def b_obj(self):
        return self._b_obj

    @b_obj.setter
    def b_obj(self,val):
        self._b_obj = val


class B:
    def __init__(self, a_obj):
        self.a_obj = a_obj

    @property
    def state(self):
        return self.a_obj.state

    @state.setter
    def state(self,val):
        self.a_obj.state = val

Я хочу, чтобы он работал следующим образом:

>>> objA = A(4)
>>> objB = objA.b_obj
>>> print objA.state
4
>>> print objB.state
4
>>> objA.state = 10
>>> print objA.state
10
>>> print objB.state
10
>>> objB.state = 1
>>> print objA.state
1
>>> print objB.state
1

Все работает так, как я хочу, за исключением последних трех команд. Они дают:

>>> objB.state = 1
>>> print objA.state
10
>>> print objB.state
1

Почему последние 3 команды возвращают эти значения? Как я могу исправить это, чтобы вернуть нужные значения?

Спасибо

4b9b3361

Ответ 1

Итак, вам все-таки нужно, чтобы ваши классы наследовали от object:-) Это дает вам классы нового стиля и все их преимущества.

class A(object):
    ...  # rest is as per your code

class B(object):
    ...  # rest is as per your code

>>> objA = A(4)
>>> objB = objA.b_obj
>>> print objA.state
4
>>> print objB.state
4
>>> objA.state = 10
>>> print objA.state
10
>>> print objB.state
10
>>> objB.state = 1
>>> print objA.state
1
>>> print objB.state
1

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

Для объектов механизм находится в object.__getattribute__(), который преобразует b.x в type(b).__dict__['x'].__get__(b, type(b)).

Для классов машина находится в type.__getattribute__(), которая преобразует b.x в B.__dict__['x'].__get__(None, B).

(из "важных точек для запоминания" )

  • __getattribute__() доступен только с новыми классами и объектами стиля

  • object.__getattribute__() и type.__getattribute__() сделать разные вызовы __get__().