2016-02-25 13 views
10

Mam klasę, która śledzi kilka innych klas. Każda z tych pozostałych klas musi mieć dostęp do wartości konkretnej zmiennej, a każda z tych innych klas musi także być w stanie zmodyfikować tę konkretną zmienną, tak aby wszystkie inne klasy mogły zobaczyć zmienioną zmienną.Python Object Property Sharing

Próbowałem tego dokonać przy użyciu właściwości. Przykładem jest następująca:

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 

chcę go do pracy w następujący sposób:

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

Wszystko działa jak chcę go z wyjątkiem ostatnich 3 komend. Podają:

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

Dlaczego ostatnie 3 polecenia zwracają te wartości? Jak mogę to naprawić, aby zwracać pożądane wartości?

Dzięki

+4

Way zadać naprawdę dobrze przemyślane, szczegółowe, konkretne pytanie zarówno z oczekiwanego i obserwowanego zachowania tylko na swojej 2nd pytanie do serwisu. Bardzo dobrze zrobione. :) –

+3

Sidenote: Jeśli korzystasz z Python27, twoje klasy powinny dziedziczyć "obiekt". I tak, zgodził się z @ g.d.d.c, bardzo dobrze napisane pytanie. – aneroid

+1

Aby zapewnić dodatkowy kontekst do opublikowanego aneroidu. Oto dokumentacja klas New Style dla Pythona 2.7: https://www.python.org/doc/newstyle/ – idjaw

Odpowiedz

5

Wygląda więc na to wszystko trzeba było zrobić, to mieć swoje klasy dziedziczą object :-) To daje new-style classes i all their benefits.

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 

Konkretne powody dlaczego to będzie działać tylko z klasami w nowym stylu, from here:

Dla obiektów, maszyna jest w object.__getattribute__() który przekształca b.x do type(b).__dict__['x'].__get__(b, type(b)).

Dla klas maszyna jest w type.__getattribute__(), która przekształca B.x w B.__dict__['x'].__get__(None, B).

(od "ważnych punktów do zapamiętania")

  • __getattribute__() jest dostępny tylko z nowych klas i stylów obiektów

  • object.__getattribute__() i type.__getattribute__() zrobić różne połączenia do __get__().

+1

Możesz dodać link do dokumentacji, który zamieściłem w komentarzu OP, aby uzyskać dodatkowe informacje, jeśli chcesz dodać trochę więcej informacji. – idjaw

+1

Dzięki, właśnie tego szukałem, by zacytować odpowiednią sekcję. – aneroid

+0

Dziękuję bardzo za pomoc! – Bedlington

Powiązane problemy