2013-04-22 14 views
11

Qui ho un attributo 'a', che è definito nel metodo di prima classe e dovrebbe essere cambiato in secondo. Quando li chiama in ordine, viene visualizzato questo messaggio:AttributeError: L'oggetto 'Class' non ha attributo 'a'

AttributeError: 'Class' object has no attribute 'a'

L'unico modo che ho trovato - definire 'a' di nuovo nel secondo metodo, ma nel codice vero e proprio è stato a lungo eredità e app sarà incasinato. Perché non funziona? Non è self.a uguale a Class.a?

class Class(object): 
    def method_1(self): 
     self.a = 1 
    def method_2(self): 
     self.a += 1 

Class().method_1() 
Class().method_2() 

risposta

14

Risposta breve, n. Il problema con il tuo codice è che ogni volta che crei una nuova istanza.

Edit: Come abarnert cita di seguito, v'è una grande differenza tra Class.a e c.a. Gli attributi di istanza (il secondo caso) appartengono a ciascun oggetto specifico, mentre gli attributi di classe appartengono alla classe. Guarda il commento di abarnert qui sotto o la discussione here per maggiori informazioni.

Il codice è equivalente al

c1 = Class() 
c1.method_1() # defines c1.a (an instance attribute) 
c2 = Class() 
c2.method_2() # c2.a undefined (the c2 instance doesn't have the attribute) 

Probabilmente vuole fare somthing come

c = Class() 
c.method_1() # c.a = 1 
c.method_2() # c.a = 2 
print "c.a is %d" % c.a # prints "c.a is 2" 

O probabilmente ancora meglio sarebbe per inizializzare c con un attributo a

class Class: 
    def __init__(self): 
     self.a = 1 # all instances will have their own a attribute 
+8

Grande rispondi ... ma probabilmente vale la pena di spiegare che 'self.a' è non uguale a 'Class.a', invece di dire semplicemente" no "). 'self.a' è un attributo _instance_: ogni istanza di' Class' ha una propria copia. 'Class.a' è un attributo _class: la classe stessa ha una singola copia, non importa quante istanze ci siano (una specie di membro statico in C++ e lingue correlate). E se non sai perché vuoi un attributo di classe, non ne vuoi uno. – abarnert

3

A appena creato istanza di Class non ha attributo a quando fate instance_of_class.method_2() senza chiamare method_1, come nel tuo esempio.

Considerate questa versione leggermente modificata del codice:

class CreateNewClassInstance(object): 
    def create_a(self): 
     self.a = 1 
    def add_one_to_a(self): 
     self.a += 1 

CreateNewClassInstance().create_a() 
CreateNewClassInstance().add_one_to_a() 

Ogni volta che si chiama Class() (o CreateNewClassInstance()) si crea un nuovo oggetto, con il suo stesso attributo a. Finché non si inizializza a, non si dispone di un attributo con quel nome.

La maggior parte delle volte questo non è un problema - tuttavia, += tenterà di caricare self.a prima di aggiungere uno ad esso - che è ciò che sta causando il AttributeError in questo caso.

Problemi correlati