2010-02-15 6 views
7

Ich bin neu bei Python so Entschuldigung im Voraus, wenn das eine dumme Frage ist.überladen erweiterte arithmetische Zuweisungen in Python

Für eine Zuweisung muss ich erweiterte arithmetische Zuweisungen (+ =, - =,/=, * =, ** =,% =) für eine Klasse myInt überladen. Ich überprüfte die Python-Dokumentation und das ist, was ich kam mit:

def __iadd__(self, other): 

    if isinstance(other, myInt): 
     self.a += other.a 
    elif type(other) == int: 
     self.a += other 
    else: 
     raise Exception("invalid argument") 

self.a und sind.Ein in jeder Klasse Instanz mit dem int gespeichert beziehen. Ich habe versucht zu testen dies wie folgt, aber jedes Mal, wenn ich 5 ‚Keine‘ statt des erwarteten Wertes zu erhalten:

c = myInt(2) 
b = myInt(3) 
c += b 
print c 

Kann mir jemand sagen, warum dies geschieht? Danke im Voraus.

+2

Ich glaube, es gibt keine dummen Fragen .. –

Antwort

14

Sie müssen return self zu Ihrer Methode hinzufügen. Erläuterung:

Die Semantik a += b, wenn type(a) eine spezielle Methode hat __iadd__, definiert sein:

a = a.__iadd__(b) 

also, wenn __iadd__ kehrt etwas anderes als self, das ist, was wird gebunden sein a nach dem nennen Betrieb. Durch das Fehlen einer return-Anweisung entspricht die von Ihnen gepostete Methode einer Methode mit return None.

+1

Alex, ich liebe deine Antworten immer! –

+0

@ Srinivas, danke! –

+0

Danke für die klare Erklärung! – Mel

1

Ja, Sie müssen „return self“, es wird wie folgt aussehen:

def __iadd__(self, other): 
    if isinstance(other, myInt): 
     self.a += other.a 
     return self 
    elif type(other) == int: 
     self.a += other 
     return self 
    else: 
     raise Exception("invalid argument") 
+2

Außerdem sollten Sie Ihre 'Exception' als' TypeError' definieren. – jcdyer

7

Augmented Operatoren in Python hat den endgültige Wert um zu dem Namen zugewiesen werden, die sie aufgerufen werden, in der Regel (und in Ihrem Fall) self. Wie bei allen Python-Methoden wird bei einer fehlenden return-Anweisung None zurückgegeben.

Auch

  • Nie jemals Exception erhöhen, was sanely zu fangen unmöglich ist. Der Code, um dies zu tun, würde except Exception sagen, die alle Ausnahmen fangen wird. In diesem Fall möchten Sie ValueError oder TypeError.
  • Keine Überprüfung mit type(foo) == SomeType. In diesen (und praktisch allen) Fällen funktioniert isinstance besser oder zumindest gleich.
  • Immer wenn Sie Ihren eigenen Typ erstellen, wie myInt, sollten Sie ihn mit Großbuchstaben benennen, damit die Leute ihn als Klassennamen erkennen können.