2010-07-24 19 views
7

vengo da un C++ sfondo a PythonDichiarazione membri solo nel costruttore

ho dichiarando variabili membro e impostandole in C++ modo esqe in questo modo:

class MyClass: 
    my_member = [] 

    def __init__(self,arg_my_member): 
     self.my_member = arg_my_member 

Poi ho notato in qualche codice open source, che la dichiarazione iniziale my_member = [] è stata completamente omessa e creata solo nel costruttore.

Che ovviamente è possibile in quanto Python è dinamico.

La mia domanda è, è questo il modo preferito o Pythonic di fare le cose, e ci sono e pro e contro di entrambi?

risposta

9

Il modo in cui lo state facendo significa che ora avrete un membro "statico" e un membro "non statico" con lo stesso nome.

class MyClass: 
    my_member = [] 

    def __init__(self, arg_my_member): 
     self.my_member = arg_my_member 


>>> a = MyClass(42) 
>>> print a.my_member 
42 
>>> print MyClass.my_member 
[] 
4

Se lo si definisce all'interno della classe, si tratta di una variabile di classe e se la si definisce all'interno del costruttore è una variabile oggetto. Quindi se non lo si definisce all'interno del costruttore TUTTE le istanze della classe condividono la stessa variabile di classe.

0

Questo crea un attributo di classe chiamata my_member

class MyClass: 
    my_member = [] 

Se le istanze non hanno una variabile di istanza denominata my_member, tutte le istanze avrebbero accesso alla lista stessa via self.my_member.

Dal momento che si sta creando una variabile di istanza denominata my_member è molto probabile che la variabile di classe non viene mai utilizzato ed è solo un segno di confusione

-1

Si tratta di due cose diverse. my_member è una variabile di classe (come un membro di una classe statica in C++ e amici) perché è creata a livello di classe. Puoi accedervi come instance.my_member, ma è condivisa tra tutte le istanze (e quindi è meglio farne riferimento come cls.my_member). Impostandoli in __init__ come self.my_member crea un membro "reale" (una variabile di istanza) per ogni istanza.

1

Entrambi i modi sono accettabili per Python, tranne nel caso di valori mutabili. Quando si dichiara che, come nel tuo esempio, è possibile ottenere risultati molto inaspettato:

>>> class MyClass: 
...  my_member = [] 
... 
>>> A = MyClass() 
>>> B = MyClass() 
>>> A.my_member.append(1) 
>>> A.my_member 
[1] 
>>> B.my_member.append(2) 
>>> B.my_member 
[1, 2] 
>>> A.my_member 
[1, 2] 
>>> MyClass.my_member 
[1, 2] 

Poiché i membri della classe vengono generati solo una volta, quando classe stessa sta per essere eseguita a carico del modulo. Se il tuo membro è destinato ad essere utilizzato nell'ambito dell'istanza, dovresti impostarlo in __init__

I valori immutabili vanno bene così.

Problemi correlati