2011-10-18 29 views

risposta

49

Se si desidera l'attributo di essere condiviso da tutte le istanze della classe, utilizzare un attributo di classe:

class A(object): 
    foo = None 

Questo provoca ('foo',None) essere una coppia (key,value) in A.__dict__.

Se si desidera l'attributo di essere personalizzabile su una base per-esempio, utilizzare un attributo esempio:

class A(object): 
    def __init__(self): 
     self.foo = None 

Questo fa sì che ('foo',None) ad essere una coppia (key,value) in a.__dict__ dove a=A() è un'istanza di A.

+1

ha senso, ho pensato che fossero limitati all'istanza in entrambi i casi ... grazie :) – fortran

+6

Python ha un insieme complicato di [regole di ricerca attributi] (http://www.cafepy.com/article/python_attributes_and_methods/ python_attributes_and_methods.html). Senza entrare nei descrittori, per questo caso è sufficiente sapere che 'a .__ dict__' viene cercato per prima cosa nella chiave' foo', e se non viene trovato lì, viene cercato 'A .__ dict__'. Questo è il motivo per cui puoi usare 'a.foo' anche se' foo' è un attributo di classe. – unutbu

+1

Degno di nota è che per gli attributi di classe, se si dovesse fare 'a.foo = whatever', si finirebbe per creare un nuovo attributo di istanza (che nasconde l'attributo di classe). 'A.foo' non sarebbe cambiato. È un po 'complicato, dal momento che è possibile accedere al valore di 'A.foo' con' a.foo', ma assegnandogli si creerebbe un nuovo attributo di istanza. – Kat

2

Gli attributi definiti nella definizione di classe sono considerati variabili di classe (come variabili statiche in Java), mentre quelli impostati nell'inizializzatore sono attributi di istanza (notare la differenza tra self.something = 1 e something = 1). Vedi this question per maggiori dettagli, e this one per ancora di più. Non c'è molta differenza pratica tra questi due casi, poiché la definizione a livello di classe fornisce un attributo di valore predefinito, ma se si desidera utilizzare un tipo di logica per impostare un attributo prima di utilizzare un'istanza di oggetto, è necessario farlo in il metodo __init__().

Problemi correlati