2012-05-23 11 views
8
#it's python 3.2.3 
class point: 
    def __init__(self, x, y): 
     self.x = x 
     self.y = y 

    def __add__(self, point): 
     self.x += point.x 
     self.y += point.y 
     return self 

    def __repr__(self): 
     return 'point(%s, %s)' % (self.x, self.y) 

class Test: 
    def __init__(self): 
     self.test1 = [point(0, i) for i in range(-1, -5, -1)] 
     self.test2 = [point(i, 0) for i in range(-1, -5, -1)] 

     print('%s\n+\n%s\n=\n%s' % (self.test1[0], self.test2[0], self.test1[0] + self.test2[0])) 

test = Test() 
input() 

L'output di questo programma èmetodo Inoltre personalizzato non riesce durante l'interpolazione stringa

point(-1, -1) 
+ 
point(-1, 0) 
= 
point(-1, -1) 

Ma dovrebbe essere

point(-1, -1) 
+ 
point(-1, 0) 
= 
point(-2, -1) 

Ma se faccio

print(point(-1, -1) + point(-1, 0)) 

Funziona perfettamente

Voglio sapere perché e come risolvere questo problema

p.s. scusa se il mio inglese è male :)

risposta

17

La tua funzione __add__ modifica l'argomento della mano sinistra su +. Per esempio:

>>> x = point(0, 0) 

>>> x + point(1, 1) 
point(1, 1) 

>>> x 
point(1, 1) 

si dovrebbe cambiare __add__ essere come

def __add__(self, oth): 
    return point(self.x + oth.x, self.y + oth.y) 
+3

Niente come incollare il codice e avere qualcun altro si batte da pochi secondi. Il mio errore è stato chiaramente prendendo il tempo di digitare "er" in "altro" .. ;-) – DSM

+1

Ma, il codice di OP restituisce l'oggetto originale, e in effetti funziona in un altro contesto. Non penso che questa sia una spiegazione sufficiente. – Marcin

+1

Sono d'accordo con @Marcin - anche se questo è l'unico problema evidente nel codice del PO, non può essere l'intera storia - li aggiunge solo una volta, e non stampa il punto di LH dopo che, solo prima. Gli effetti collaterali non dovrebbero essere notati da questo particolare caso di test. A meno che non sia possibile valutare i tuple letterali in ordine errato? – lvc

3

Tu dici l'uscita dovrebbe essere:

point(-1, -1) 
+ 
point(-1, 0) 
= 
point(-2, -1) 

in realtà dovrebbe essere:

point(0, -1) 
+ 
point(-1, 0) 
= 
point(-1, -1) 

Perché stai creando quel primo punto con [point(0, i) for i in range(-1, -5, -1)] (notare che il parametro x è 0).

Questa è una conseguenza di (self.test1[0], self.test2[0], self.test1[0] + self.test2[0])) in corso di valutazione - l'aggiunta modifica il primo punto in tale tupla (sono lo stesso oggetto). Questo è anche il motivo per cui il secondo esempio funziona correttamente (o sembra) - si stampa l'oggetto modificato solo una volta.

L'implementazione di __add__ fornita è adatta per __iadd__ per implementare l'operatore +=. Una corretta attuazione dovrebbe creare un nuovo oggetto point:

def __add__(self, oth): 
    return point(self.x + oth.x, self.y + oth.y) 
+0

Sì, ora lo so – foxneSs

Problemi correlati