7
votes

Affectation des composés à la classe Python et les variables d'instance

J'essaie de comprendre la manipulation de Python de la classe et des variables d'instance. En particulier, j'ai trouvé Cette réponse assez utile. Fondamentalement, il dit que si vous déclarez une variable de classe, puis vous effectuez une affectation à [instance] .property code>, vous attribuerez à une variable différente totalement - une dans un espace de noms différent de la classe. variable.

Alors j'ai envisagé - si je veux que chaque instance de ma classe ait un membre avec une valeur par défaut (disons zéro), dois-je le faire comme suit: P>

class Foo:
    num = 0

bar = Foo()
bar.num += 1 # good, no error here, meaning that bar has an attribute 'num'
bar.num
>>> 1
Foo.num
>>> 0 # yet the class variable is not modified! so what 'num' did I add to just now?


0 commentaires

5 Réponses :


0
votes
bar.foo = 5
print bar.foo

3 commentaires

Euh ... bar.foo + = 1 donne également une erreur, donc clairement Python ne crée pas de variables d'instance chaque fois qu'il les rencontre dans une expression contenant '+ ='. Ma question est que la création de variables de classe conduit à l'initialisation des variables d'instance correspondantes?


@ int3. Cela concerne comment les attributs sont résolus. Lorsque vous accédez à un attribut, l'objet est recherché en premier ( num dans ce cas), puis le type de l'objet ( foo ) dans ce cas, puis les classes de base du type de l'objet et leurs bases. Si aucun attribut correspondant n'est trouvé attributeError est soulevé.


En effet, puis la variable d'instance est créée parce que nous lui attribuons une valeur. Je vais mettre à jour l'exemple



-3
votes

Je pense que vous venez de trouver un bogue dans Python là-bas. bar.num + = 1 devrait être une erreur, à la place, il crée un numéro d'attribut dans la barre d'objet, distincte de Foo.num.

C'est un comportement vraiment étrange.


4 commentaires

@Morgaelyn: non ce n'est pas un bogue, c'est un comportement prévu. Lisez sur les classes Python Docs.python.org/Tutorial/classes.html


Comme le dit Matth, ce comportement prévu et documenté. Donc, non, ce n'est pas un bug.


Maintenant j'ai compris. b.num + = 1 est la même chose que b.num = b.num + 1. Le premier B.Num fait référence à l'attribut d'objet et est créé. Le second B.num fait référence effectivement à foo.num et est 0. Maintenant cela a du sens. Je respecte toujours qu'il s'agit d'une erreur de conception dans la langue. Il est facile de supposer que b.num in b.num + = 1 fait toujours référence à la même variable, mais elle fait en réalité référence à deux variables non liées en même temps.


Pas une erreur de conception. C'est un détail de mise en œuvre. Vous n'occupez généralement pas un attribut de classe avec un attribut d'instance.



5
votes

Personnellement, j'ai trouvé Ces documents par Shalabh Chaturvedi extrêmement utile et informatif concernant ce sujet.

bar.num + = 1 est un raccourci pour bar.num = bar.num + 1 . Ceci est en train de ramasser la variable de classe foo.num sur le côté droit et l'attribuant à une variable d'instance bar.num . .


1 commentaires

Et quand je dis que je dis la classe / instance variable ce que je veux vraiment dire est attribut .



2
votes

Dans le code suivant, num code> est un élément de classe.

struct Foo {
  int num;
};


1 commentaires

Votre équivalent C ++ semble avoir incrémenter la valeur du nombre de 1! :)



0
votes

Recherche de cette question très question, cette question de Stackoverflow et deux (assez vieilles, mais valides) par Guido Van Rossum ( 1 , 2 ) est arrivé haut. Diapositives de Guido State State Ce problème concerne la commande de recherche de Python pour accéder à l'attribut (dans le cas de l'exemple ci-dessus num ). Pensait que ce serait bien de mettre les deux ensemble ici :)


0 commentaires