2012-01-03 7 views
6

Dizionari e elenchi definiti direttamente sotto la definizione di classe funzionano come statici (ad esempio this question)
Come mai altre variabili come intero non lo fanno?Perché alcune variabili di classe sembrano agire come statiche mentre altre no?

>>> class Foo(): 
     bar=1 

>>> a=Foo() 
>>> b=Foo() 
>>> a.bar=4 
>>> b.bar 
1 
>>> class Foo(): 
     bar={} 

>>> a=Foo() 
>>> b=Foo() 
>>> a.bar[7]=8 
>>> b.bar 
{7: 8} 
+0

controllo risposta omnifarious [qui] (http://stackoverflow.com/questions/8701500/python-class-instance-variables-and-class-variables/8701647#8701647) – joaquin

+0

possibile duplicato di http://stackoverflow.com/questions/68645/static-class-variables-in-python – gecco

risposta

15

Sono tutte variabili di classe. Tranne quando hai assegnato a.bar=4 creando una variabile di istanza. Fondamentalmente Python ha un ordine di ricerca sugli attributi. Si va:

instance -> class -> parent classes in MRO order (left to right) 

Quindi, se avete

class Foo(object): 
    bar = 1 

Questa è una variabile sulla classe Foo. Una volta fatto

a = Foo() 
a.bar = 2 

è stata creata una nuova variabile sull'oggetto a con il nome bar. Se guardi allo a.__class__.bar vedrai ancora 1, ma è effettivamente nascosto a causa dell'ordine menzionato in precedenza.

Il codice creato dall'utente è a livello di classe, quindi è condiviso tra tutte le istanze di tale classe.

6

Quando si effettua l'assegnazione

>>> a.bar=4 

si sono rebinding il Foo.bar nome 4, che è una nuova istanza di un numero intero. D'altra parte,

>>> a.bar[7]=8 

non Vuol associare nuovamente Foo.bar a qualcosa di diverso, e semplicemente modifica il dizionario che il nome si riferisce.

Se fai

>>> a.bar = {7: 8} 

allora si avrà associare nuovamente Foo.bar ad un nuovo dizionario .

1

Supponendo a è un'istanza di A e A ha un attributo di classe bar:

  • a.bar = 4 crea attributo un'istanza bar che nasconde la classe bar nel contesto a

  • a.bar[4] = 2 solo modifica l'oggetto a cui si associa il livello di classe bar (supponendo che supporti l'indicizzazione)

  • a.bar += 1 - Questo è sgradevole. Se il livello di classe bar supporta l'operazione += (ad esempio implementando __iadd__()), viene modificato sul posto e non viene creato alcun attributo a livello di oggetto. Altrimenti è equivalente a a.bar = a.bar + 1 e viene creato un nuovo attributo di istanza bar.

Problemi correlati