2016-02-25 14 views
10

Ich habe eine Klasse, die mehrere andere Klassen verfolgt. Jede dieser anderen Klassen muss alle auf den Wert einer bestimmten Variablen zugreifen, und jede dieser anderen Klassen muss auch in der Lage sein, diese bestimmte Variable zu modifizieren, so dass alle anderen Klassen die geänderte Variable sehen können.Python-Objekt-Property-Sharing

Ich habe versucht, dies mit Eigenschaften zu erreichen. Ein Beispiel hierfür ist wie folgt:

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 

Ich will es wie folgt arbeiten:

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

Alles funktioniert, wie ich es für die letzten drei Befehle ausnehmen wollen. Sie geben:

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

Warum geben die letzten 3 Befehle diese Werte zurück? Wie kann ich das beheben, damit sie die gewünschten Werte zurückgeben?

Dank

+4

Way auf nur Ihre zweite Frage auf der Website ein wirklich gut durchdacht, detaillierte, konkrete Frage mit sowohl erwartete als auch beobachtete Verhalten zu fragen. Sehr gut gemacht. :) –

+3

Hinweis: Wenn Sie Python27 verwenden, sollten Ihre Klassen 'object' erben. Und ja, einverstanden mit @ g.d.d.c, sehr gut geschriebene Frage. – aneroid

+1

Um zusätzlichen Kontext zu liefern, was Aneroid gepostet hat. Hier ist Dokumentation über neue Stilklassen für Python 2.7: https://www.python.org/doc/newstyle/ – idjaw

Antwort

5

So scheint es, alles, was Sie tun müssen, um Ihre Klassen von object erben ist :-) Dass man new-style classes und all their benefits gibt.

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 

Die spezifischen Gründe dafür, warum diese Klassen nur mit neuem Stil funktionieren würde, from here:

Für Objekte, die Maschinen in object.__getattribute__() die b.x in type(b).__dict__['x'].__get__(b, type(b)) verwandelt.

Für Klassen ist die Maschine in type.__getattribute__(), die B.x in B.__dict__['x'].__get__(None, B) umwandelt.

(von "wichtigen Punkten zu erinnern")

  • __getattribute__() mit neuen Stilklassen nur verfügbar ist, und Objekte

  • object.__getattribute__() und type.__getattribute__() verschiedene Anrufe __get__() machen.

+1

Sie können den Dokumentationslink hinzufügen, den ich im OP-Kommentar für zusätzliche Informationen gepostet habe, wenn Sie ein wenig mehr Informationen hinzufügen möchten. – idjaw

+1

Danke, ich habe nur gesucht, um den entsprechenden Abschnitt zu zitieren. – aneroid

+0

Vielen Dank für Ihre Hilfe! – Bedlington