Python Object Property Sharing
Question: I have a class that keeps track of several other classes. Each of these other
classes all need to access the value of a particular variable, and any one of
these other classes must also be able to modify this particular variable such
that all other classes can see the changed variable.

I tried to accomplish this using properties. An example is as follows:

    
    
    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
    

I want it to work as follows:

    
    
    >>> 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
    

Everything works as I want it to except for the last 3 commands. They give:

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

Why do the last 3 commands return these values? How can I fix this so that
they return the desired values?

Thanks


Answer: So it seems all you needed to do is have your classes inherit from `object`
:-) That gives you [new-style
classes](https://docs.python.org/2/reference/datamodel.html#newstyle) and [all
their benefits](https://www.python.org/doc/newstyle/).

    
    
    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
    

The specific reasons for why this would work only with new-style classes,
[from here](https://docs.python.org/2/howto/descriptor.html#invoking-
descriptors):

> For objects, the machinery is in `object.__getattribute__()` which
> transforms `b.x` into `type(b).__dict__['x'].__get__(b, type(b))`.
>
> For classes, the machinery is in `type.__getattribute__()` which transforms
> `B.x` into `B.__dict__['x'].__get__(None, B)`.
>
> (from "important points to remember")
>
>   * `__getattribute__()` is only available with new style classes and
> objects
>
>   * `object.__getattribute__()` and `type.__getattribute__()` make different
> calls to `__get__()`.
>
>

