2017-01-15 7 views
0

In Python ist es möglich, Zugriff auf den aktuellen Wert einer Klassenvariablen innerhalb seiner Setter?Zugreifen auf den aktuellen Wert der Eigenschaft in Setter

Zum Beispiel:

# Getter 
@property 
# ... 

# Setter 
@position.setter 
def position(self, value): 
    # Do something with current value... 
    # self.position, self.__position, position and __position don't seem to work 

    # Update position with the given value 
    self.__position = value 

    # Do something with the new value... 

Das Äquivalent in C# wäre:

private Position position; 

public Position Position 
{ 
    get 
    { 
     // ... 
    } 

    set 
    { 
     // Do something with the current value... 

     // Update position field with given object 
     position = value; 

     // Do something with the new value... 
    } 
} 

aktualisieren
Hier ist ein Minimal, Complete, und prüfbare Beispiel besser, meine Frage zu veranschaulichen:

class C: 
    def __init__(self): 
     self.x = 2 

    @property 
    def x(self): 
     return self.__x 

    @x.setter 
    def x(self, value): 
     print(self.x) 
     self.__x = value 
     print(self.x) 

c = C() 

Der folgende Fehler ausgelöst:

AttributeError: 'C' object has no attribute '_C__x' 

Dies tritt auf, weil die setter versucht vor dem Aktualisieren sie die Variable den aktuellen Wert zu drucken, und die Einstelleinrichtung ausgeführt wird, wenn x bis 2 Innen __init__ festgelegt ist, an welchem ​​Punkt x hat zuvor wurde kein Wert zugewiesen (es gibt keinen aktuellen Wert zum Drucken).

+1

Was tun du meinst * "schein nicht zu arbeiten" *? Bis Sie ihm zugewiesen haben, ist "self .__ position" immer noch der alte Wert und "self.position" wird daher auch auf den alten Wert zugreifen. – jonrsharpe

+0

Das war, was ich dachte, aber der Versuch, auf "self.position" oder "self .__ position" im Setter zuzugreifen, führt beide zu folgendem Fehler: 'AttributeError: 'GameObject' Objekt hat kein Attribut '_GameObject__position'. ('GameObject' ist die Klasse, die die 'position'-Variable enthält.) – Ruben9922

+0

Bitte gib ein [mcve]. Denken Sie auch daran, den '__double_underscore' zu ​​verwerfen, da ein Name Mangling die Dinge unnötig kompliziert. – jonrsharpe

Antwort

1

Sie setzen self.x (mit dem Setzer) in Ihrem __init__. Aber in Ihrem x.setter Sie print(self.x) (mit dem Getter) vor der tatsächlichen Einstellung Ihres Wertes.

Sie könnten einen Standard-Wert (zum Beispiel als Klassenattribut) definieren, damit es funktioniert:

class C: 
    __x = None 

    def __init__(self): 
     self.x = 2 

    @property 
    def x(self): 
     return self.__x 

    @x.setter 
    def x(self, value): 
     print(self.x) 
     self.__x = value 
     print(self.x) 

>>> c = C() 
None 
2 

Beachten Sie, dass doppelt unterstrichene Variablen unterliegen dem "name mangling" und der Konvention ist, dass man stattdessen einzelne unterstrichene Variablen verwendet .

wäre eine andere Art und Weise zu try darauf zugreifen und wenn es dann etwas anderes nicht verfügbar ist zurückkehren (oder etwas anderes tun):

class C: 
    def __init__(self): 
     self.x = 2 

    @property 
    def x(self): 
     try: 
      return self.__x 
     except AttributeError: 
      # I return "None" here but you could also do something else 
      return None 

    @x.setter 
    def x(self, value): 
     print(self.x) 
     self.__x = value 
     print(self.x) 

, die das gleiche Ergebnis liefert:

>>> c = C() 
None 
2 
+0

Ich frage mich nur, gibt es eine Möglichkeit, dies zu tun, ohne die Variable "statisch" zu machen (ohne "__x" außerhalb von "__init__" zu initialisieren)? – Ruben9922

+0

@ Ruben9922 Ich habe einen anderen Weg hinzugefügt, der die Ausnahme im "Getter" fängt. Beantwortet das deine Frage? Beachte, dass du auch die "try", "except" um die erste 'print'-Anweisung in deinem Setter machen kannst. Vielleicht, um das zu überspringen, wenn noch kein Attribut festgelegt wurde. – MSeifert

+0

Oh ok. Ja, das beantwortet meine Frage - danke! – Ruben9922

Verwandte Themen