Come per tutti i buoni esempi, hai semplificato ciò che stai effettivamente cercando di fare. Questo è buono, ma vale la pena notare che python ha molta flessibilità quando si tratta di variabili di classe rispetto a istanze. Lo stesso si può dire dei metodi. Per un buon elenco di possibilità, raccomando di leggere la presentazione del nuovo stile di Michael Fötsch , in particolare le sezioni da 2 a 6.
Una cosa che richiede molto lavoro da ricordare quando si inizia è che Python non è Java. Più che un semplice cliché. In Java, viene compilata un'intera classe, semplificando la risoluzione dello spazio dei nomi: qualsiasi variabile dichiarata al di fuori di un metodo (ovunque) è variabile di istanza (o, se statica, classe) e è implicitamente accessibile all'interno dei metodi.
Con Python, la grande regola empirica è che ci sono tre spazi dei nomi che vengono ricercati, in ordine, per le variabili:
- La funzione / metodo
- Il modulo attuale
- builtins
{begin pedagogy}
Ci sono limitate eccezioni a questo. Quello principale che mi viene in mente è che, quando viene caricata una definizione di classe, la definizione di classe è il suo spazio dei nomi implicito. Ma questo dura solo fino a quando il modulo viene caricato, ed è completamente bypassato all'interno di un metodo. Così:
>>> class A(object):
foo = 'foo'
bar = foo
>>> A.foo
'foo'
>>> A.bar
'foo'
ma:
>>> class B(object):
foo = 'foo'
def get_foo():
return foo
bar = get_foo()
Traceback (most recent call last):
File "<pyshell#11>", line 1, in <module>
class B(object):
File "<pyshell#11>", line 5, in B
bar = get_foo()
File "<pyshell#11>", line 4, in get_foo
return foo
NameError: global name 'foo' is not defined
{end pedagogy}
Alla fine, la cosa da ricordare è che non ha accesso a nessuna delle variabili che si desidera accedere, ma probabilmente non in modo implicito. Se i tuoi obiettivi sono semplici e chiari, probabilmente sarà sufficiente scegliere Foo.bar o self.bar. Se il tuo esempio sta diventando più complicato, o vuoi fare cose fantasiose come l'ereditarietà (puoi ereditare metodi statici / di classe!) O l'idea di fare riferimento al nome della tua classe all'interno della classe stessa ti sembra sbagliata, dai un'occhiata l'intro che ho collegato.