2010-02-15 3 views
7

Jestem nowy w Pythonie, więc przepraszam z góry, jeśli to głupie pytanie.Przeciążanie zwiększonych zadań arytmetycznych w pytonie

Do zadania potrzebuję przeciążać zwiększone przypisania arytmetyczne (+ =, - =,/=, * =, ** =,% =) dla klasy myInt. Sprawdziłem w dokumentacji Pythona i to, co wymyśliłem:

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 i other.a odnoszą się do int przechowywanych w każdej instancji klasy. Próbowałem testowania to w następujący sposób, ale za każdym razem mam „Brak” zamiast oczekiwanej wartości 5:

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

Czy ktoś może mi powiedzieć, dlaczego tak się dzieje? Z góry dziękuję.

+2

Wierzę, że nie ma głupich pytań .. –

Odpowiedz

14

Musisz dodać return self do swojej metody. Objaśnienie:

Semantyka a += b, gdy type(a) posiada specjalną metodę __iadd__, są zdefiniowane jako:

a = a.__iadd__(b) 

więc jeśli __iadd__ powraca coś innego niż self, to co będzie związany nazwać a po sobie operacja. Brakujące oświadczenie return, wysłana metoda jest równoważna z return None.

+1

Alex, zawsze uwielbiam twoje odpowiedzi! –

+0

@Srinivas, dzięki! –

+0

Dzięki za jasne wyjaśnienie! – Mel

1

Tak, trzeba „ja zwrotny”, będzie to wyglądać tak:

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

Powinieneś również uczynić swój wyjątek 'TypeError'. – jcdyer

7

Augmented operatorów w Pythonie musiał wrócić ostateczną wartość, jaka zostanie przypisana do nazwy ich wezwał, zwykle (i w twoim przypadku) self. Podobnie jak wszystkie metody Pythona, brak instrukcji return oznacza zwrócenie None.

Również

  • Nigdy kiedykolwiek podnieść Exception, co jest niemożliwe, aby złapać zdrowo. Kod do tego będzie musiał powiedzieć except Exception, który będzie złapać wszystkie wyjątków. W takim przypadku potrzebujesz ValueError lub TypeError.
  • Nie należy sprawdzać typowo z type(foo) == SomeType. W tych (i praktycznie wszystkich) przypadkach, isinstance działa lepiej lub przynajmniej tak samo.
  • Za każdym razem, gdy tworzysz własny typ, na przykład myInt, powinieneś nazwać go wielkimi literami, aby ludzie mogli je rozpoznać jako nazwę klasy.