2015-05-20 25 views
5

ho creato il seguente classe che rappresenta una cassa in cui i giocattoli (numeri) possono essere memorizzati:In un ciclo in Python, assegno una nuova istanza di una classe alla stessa variabile, ma continua a puntare alla vecchia istanza?

class Chest: 

    toys = [] 

    def __init__(self): 
    return 

    def add(self, num): 
    self.toys.append(num) 
    return 

Il codice principale che utilizza questa classe è la seguente:

room_of_chests = [] 

for i in range(3): 

    print "Chest", i 
    temp = Chest() 

    print "Number of toys in the chest:", len(temp.toys) 

    for j in range(5): 
    temp.add(j) 

    print "Number of toys in the chest:", len(temp.toys) 
    print "" 

    room_of_chests.append(temp) 

Quindi, per ogni iterazione di i, creo un nuovo Petto e trasformo la variabile temp punto (corretto?). Quindi, in teoria, in ogni iterazione, la temperatura inizia con una cassa vuota e termina con una cassa con 5 giocattoli (corretta?).

Pertanto, l'uscita mi aspetto è:

Chest 0 
Number of toys in the chest: 0 
Number of toys in the chest: 5 

Chest 1 
Number of toys in the chest: 0 
Number of toys in the chest: 5 

Chest 2 
Number of toys in the chest: 0 
Number of toys in the chest: 5 

Tuttavia, quello che sto in realtà sempre è:

Chest 0 
Number of toys in the chest: 0 
Number of toys in the chest: 5 

Chest 1 
Number of toys in the chest: 5 
Number of toys in the chest: 10 

Chest 2 
Number of toys in the chest: 10 
Number of toys in the chest: 15 

Che cosa sto facendo di sbagliato? Qualcuno può dare una rapida spiegazione di come funziona l'istanziazione in questo caso? E le regole delle variabili che puntano agli oggetti in Python? Grazie in anticipo.

risposta

10

Il problema è che si dispone di un attributo di classe e non di una variabile di istanza. Modifica la classe per trasformarla in una variabile di istanza creandola nella funzione __init__ come membro di self.

Inoltre, non è necessario utilizzare return in __init__.

class Chest: 

    def __init__(self): 
    self.toys = [] 


    def add(self, num): 
    self.toys.append(num) 

Questo è un errore comune se provieni da una lingua come Java o C++.

+1

Gli attributi di classe Python non corrispondono alle variabili dei membri statici Java o C++. I documenti Python sono molto cauti nell'evitare di usare il termine "variabile statica" o "attributo statico" ovunque per evitare di implicare qualcosa che non è vero, e sarebbe meglio fare lo stesso qui. (Altrimenti, ottima spiegazione.) – abarnert

+0

@abarnert, Grazie per il commento. Aggiornerò la terminologia – merlin2011

+0

Oh, anche, '__init__' è l'inizializzatore; il costruttore (di cui raramente ci si deve preoccupare) è '__new__'. – abarnert