PDA

View Full Version : [Python] Attributi di classe


Unrue
01-01-2010, 14:18
Ciao,
studiando Python, arrivato agli attributi di classe, ho letto che se definisco ad esempio:


class prova():
lista = [0,1]
pass

A = prova()

B = prova()

A.lista[0] = 3



Facendo così, modifico anche la lista di B. In pratica, gli attributi di classe mutable non sono static, parlando alla C++. Quelli unmutable invece non hanno questo comportamento, in quanto viene creato un riferimento ad un nuovo oggetto unmutable :


class prova():
x = 10
pass




Quindi potremmo dire che sono "statici",anche se le motivazioni sono differenti tra Python e C++. Ora, se fino a qua non ho detto fesserie :D , non ho capito il vantaggio di avere questa implementazione rispetto a quella stile C++ con attributi di classe statici o non statici. Quello che ho capito è che in Python non si dovrebbe mai modificare gli attributi di classe e gli attributi non statici (credo) sono rimpiazzati con attributi di istanza creati al volo. Cioè, in parole povere, perché non c'è una netta distinzione tra attributi statici e non statici?

cdimauro
01-01-2010, 16:38
Non è esattamente così. Gli attributi che definisci all'interno di una classe sono condivisi da tutte le istanze della medesima.

Il problema sorge quando provi ad assegnargli un valore tramite un'istanza della classe: in questo caso Python crea sempre un nuovo attributo per quell'istanza, ma non modifica l'attributo di classe, che rimane ancora presente (ma non è "visibile" dall'istanza, perché quando vi accedi per primo referenzi sempre quello dell'istanza).

Ovviamente se modifichi in qualche modo (SENZA un assegnamento) degli attribuiti di classe che sono mutabili, le modifiche si ripercuotono su tutte le istanze per le quali tale attributo è direttamente visibile.

Esempio:
>>> class c:
... lista = [0, 1]
... x = 10
...
>>> a = c()
>>> b = c()
>>> a.lista
[0, 1]
>>> a.lista[0] = 3
>>> a.lista
[3, 1]
>>> c.lista
[3, 1]
>>> b.lista
[3, 1]
>>> a.x
10
>>> a.x = 20
>>> a.x
20
>>> c.x
10
>>> c.x
10
>>> a.lista = []
>>> c.lista
[3, 1]
>>> a.lista
[]