2010-02-15 1 views
7

Sono nuovo in Python quindi scuso in anticipo se questa è una domanda stupida.Sovraccarico di compiti aritmetici aumentati in python

Per un incarico ho bisogno di sovraccaricare le assegnazioni aritmetiche aumentate (+ =, - =,/=, * =, ** =,% =) per una classe myInt. Ho controllato la documentazione Python e questo è ciò che mi si avvicinò con:

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 e perdono fra riferisco al int memorizzate in ogni istanza di classe. Ho provato a testare questa come segue, ma ogni volta che mi 'Nessuno' invece del valore atteso 5:

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

qualcuno può dirmi perché questo sta accadendo? Grazie in anticipo.

+2

Credo non ci siano domande stupide .. –

risposta

14

È necessario aggiungere return self al metodo. Spiegazione:

La semantica di a += b, quando type(a) ha un metodo speciale __iadd__, sono definiti da:

a = a.__iadd__(b) 

quindi se __iadd__ restituisce qualcosa di diverso da self, questo è ciò che sarà legato per citarne a dopo la operazione. Manca una dichiarazione return, il metodo che hai postato è equivalente a uno con return None.

+1

Alex, adoro le tue risposte! –

+0

@ Srinivas, grazie! –

+0

Grazie per la chiara spiegazione! – Mel

1

Sì, avete bisogno di "ritorno automatico", che sarà simile a questa:

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

Inoltre, dovresti rendere il tuo 'Exception' a' TypeError'. – jcdyer

7

operatori Augmented in Python hanno per restituire il valore finale da assegnare al nome con cui vengono chiamati, di solito (e nel tuo caso) self. Come tutti i metodi Python, manca un'istruzione di ritorno che implica la restituzione di None.

Inoltre,

  • Mai mai mai alzare Exception, che è impossibile da catturare in modo sano. Il codice per farlo dovrebbe dire except Exception, che catturerà tutte le eccezioni. In questo caso si desidera ValueError o TypeError.
  • Non digitare con type(foo) == SomeType. In questo (e praticamente tutti) casi, isinstance funziona meglio o almeno lo stesso.
  • Ogni volta che si crea il proprio tipo, ad esempio myInt, è necessario denominarlo con lettere maiuscole in modo che le persone possano riconoscerlo come un nome di classe.