So stieß ich heute in meinem Code auf diesen bösen Bug. Ich habe gerade Python-Eigenschaften verwendet und verwendet, um den alten Wert der Eigenschaft in einer anderen Variablen beizubehalten, wenn die Eigenschaft aktualisiert wurde. Also, wenn die Setter-Funktion aufgerufen wird, brauchte ich den alten Wert zu speichern, und dann den neuen Wert zu übertragen.Ist das ein Fehler? Python-Eigenschaft funktioniert nicht richtig mit + =
Es stellt sich heraus, dass bei Verwendung +=
für eine Eigenschaft die __iadd__
Methode aufgerufen wird, die Eigenschaft vor Ort zu aktualisieren, dann wird der Setter aufgerufen. Aber zu dieser Zeit ist der alte Wert verloren. Hier ist ein Code, der das Problem veranschaulicht.
class Container(object):
def __init__(self, val):
self.val = val
def __add__(self, other):
print('in __add__', other)
return Container(self.val + other.val)
def __iadd__(self, other):
print('in __iadd__:', other)
self.val += other.val
return self
def __str__(self):
return str(self.val)
class Test:
def __init__(self):
self._val = Container(0)
@property
def val(self):
return self._val
@val.setter
def val(self, values):
print("changing from {} to {}".format(self._val, values))
self._val = values
test = Test()
print('val=', test.val)
test.val = Container(2)
print('val=', test.val)
test.val = test.val + Container(1)
print('val=', test.val)
test.val += Container(1)
print('val=', test.val)
test.val.__iadd__(Container(1))
print('val=', test.val)
Bei der Ausführung gibt es dieses Ergebnis:
val= 0
changing from 0 to 2
val= 2
in __add__ 1
changing from 2 to 3
val= 3
in __iadd__: 1
changing from 4 to 4
val= 4
in __iadd__: 1
val= 5
Es sagt, dass es 4 bis 4 zu ändern, aber es ist wirklich 3 bis 4 verändert und dass verpasst wurde. Ich frage mich also, ob das ein Fehler ist, mir etwas fehlt oder ich einfach nicht + = verwenden soll, wenn ich mit einer Eigenschaft zu tun habe und den alten Wert brauche.
Vielleicht möchten Sie auschecken http://stackoverflow.com/questions/11987949/how-to-implement-iadd-for-a -python-property – Jan
Das hat fast geholfen. Wenn ich gerade "__iadd__" durch "__add__" auf den Objekten ersetzt hätte, würde es das beheben. Aber nur mein Glück '__Iadd__' ist ein Ready-Only-Attribut für numpige Arrays. Also habe ich den Setter einfach losgeworden und ihn zu einer Nicht-Eigentums-Set-Funktion gemacht. – TheLoneMilkMan