2017-10-18 2 views
0

Voici un petit exemple de code:Confus au sujet de la classe statique vars en python

class A: 
    staticvar=3; 

    def foo2(self): 
     print("------ Foo2") 
     print("static: "+str(A.staticvar)); 
     print("instance: "+ str(self.staticvar)); 

class B(A): 

    def setStaticVar(self, num): 
     B.staticvar=num; 


a=A(); 
b=B(); 

a.staticvar=7; 
a.foo2(); 

b.setStaticVar(100); 

a.foo2(); 

b.foo2(); 

ce que les résultats dans:

------ 
static: 3 
instance: 7 -->correct. Instance var modified 
------ 
static: 3 
instance: 7 --> Not correct. Why static var is not 100 
------ 
static: 3 
instance: 100 --> Correct, but this value should be shared between A and B 

Pourquoi cela se produit? La variable statique ne devrait-elle pas être partagée entre A et B? Pourquoi quand il est modifié en b à b. De cet exemple, il semble que chaque classe possède sa propre variable statique (pas vraiment statique à mon point de vue car il n'y aurait qu'une variable statique et nous en aurons 2, une par classe).

Quelqu'un peut-il expliquer ce comportement?

Cheers.

Répondre

0

Je suppose que vous êtes confronté à un problème de résolution de noms. Lorsque vous obtenez B.staticvar, l'interpréteur ne parvient pas à le trouver et retombe sur ses super classes pour essayer de résoudre le nom. Lors de la traversée vers A, l'interpréteur trouve staticvar et renvoie la valeur.

Lorsque vous définissez une valeur à B.staticvar, cependant, vous obtenez beaucoup plus le même comportement que votre cas, où une nouvelle propriété « instance » appelé staticvar est ajouté à B. Maintenant, lorsqu'il tente de résoudre le nom de la propriété sur B (ou des instances de celui-ci), il utilise cette nouvelle valeur sans jamais revenir à A. En Python, hériter d'une classe ne consiste pas à partager ses propriétés, il s'agit de définir une classe de secours pour résoudre les noms lorsqu'ils ne sont pas définis dans votre classe enfant (d'où l'inutilité de "redéfinir" explicitement les méthodes N'oubliez pas d'appeler super(A).method_name au sein de B.method_name si vous voulez que la fonction parente soit exécutée).

Pour obtenir le comportement que vous vous demandez, soit définir setStaticVar dans A, et/ou modifier son corps à A.staticvar=num

+0

Et comment est-il, que la classe possédante ne peut être accesed un var statique par A. staticvar ou self.staticvar dans la classe? Ne devrait-il pas lancer une erreur lors de l'utilisation de print (self.staticvar) car il ne peut pas résoudre l'instance var? – Notbad

+1

La résolution de nom sur une instance de classe commence sur l'instance, puis revient sur la classe elle-même. Par exemple, les méthodes d'une classe sont définies sur la classe, pas sur ses instances, mais vous pouvez les appeler sur une instance. Par exemple, étant donné 'a = A()', 'a.setStaticVar (5)' résout en 'A.setStaticVar (a, 5)', et en fait vous pouvez simplement écrire cette deuxième ligne et il se comportera exactement le même. De même, 'staticvar' existe dans' A', peut être accédé par 'a', ou peut être ombré en définissant une propriété de' a' avec le même nom. – scnerd

+1

En général, dans un langage dynamiquement typé comme Python (et je crois qu'il en va de même pour JS et des langages similaires), pensez aux "classes" et aux "instances" uniquement en termes de mappages de noms à des valeurs avec un arbre de sauvegardes que vous pouvez aller à si le nom ne résout pas à un moment donné. Les objets, les types, les modules et même les contextes locaux (fermetures) ne sont que des dictionnaires pouvant s'imbriquer les uns dans les autres. Vous pouvez jouer à des jeux pour modifier ces dictionnaires à différents niveaux, mais il n'y a pas beaucoup d'idée de variables "statiques" dans un tel langage. – scnerd