2010-08-02 5 views
1

De Plongez dans Python:variables de classe Python ou variables de classe en général

attributs de classe sont disponibles à la fois par référence directe à la classe et par une instance de la classe.

Les attributs de classe peuvent être utilisés comme des constantes au niveau de la classe, mais ils sont et ne sont pas vraiment des constantes. Vous pouvez également les changer.

Je tape ceci dans IDLE:

IDLE 2.6.5  
>>> class c: 
     counter=0 


>>> c 
<class __main__.c at 0xb64cb1dc> 
>>> v=c() 
>>> v.__class__ 
<class __main__.c at 0xb64cb1dc> 
>>> v.counter += 1 
>>> v.counter 
1 
>>> c.counter 
0 
>>> 

Alors qu'est-ce que je fais mal? Pourquoi la variable de classe ne conserve pas sa valeur à la fois par référence directe à la classe et à travers une instance de la classe.

+0

Puisque c.counter est toujours 0, vous n'avez évidemment pas changé sa valeur. Vous avez modifié la valeur de l'attribut compteur de l'instance v. –

+0

Vous cherchez des "variables de classe statique", je pense. Peut-être un doublon de http: // stackoverflow.com/questions/68645/static-class-variables-in-python –

Répondre

8

Parce que ints sont immuables en python

v.counter += 1 

reliaisons v.counter à un nouvel objet int. Le reconsolidation crée une instance d'attribut qui masque l'attribut class

Vous pouvez voir ce qui se passe si vous regardez le id() de v.counter

>>> id(v.counter) 
149265780 
>>> v.counter+=1 
>>> id(v.counter) 
149265768 

Ici vous pouvez voir que v a maintenant un nouvel attribut dans son __dict__

>>> v=c() 
>>> v.__dict__ 
{} 
>>> v.counter+=1 
>>> v.__dict__ 
{'counter': 1} 

contraste le cas où counter est mutable, par exemple un list

>>> class c: 
... counter=[] 
... 
>>> v=c() 
>>> v.counter+=[1] 
>>> c.counter 
[1] 
>>> 
+0

Je voudrais le mot: un nouvel objet int ... à 'v.counter' –

+0

génial, merci! – user284094

0

Vous êtes confondu entre déclaration et instanciation.

C est le nom d'une classe que vous avez déclarée.

v est un objet, instancié à partir de c.

+0

Ce n'est pas la confusion ici. Si vous définissez une variable sur une classe, vous pouvez très bien la lire exactement comme ci-dessus: instance.classvariable. –

0

Avant:

c.counter = 0 
v.counter -> c.counter 

Au cours:

c.counter = 0 
v.counter = c.counter + 1 

Après:

c.counter = 0 
v.counter = 1 
0

Notez que vous pouvez toujours obtenir à la valeur de la classe:

v.__class__.__dict__['counter'] 

vous permettra de lire ou de définir votre classe, même si vous avez obscurci le symbole en ajoutant un symbole à __dict__ de votre instance.

Questions connexes