Sites


Initiation à python

Manipulations d’attributs

Manipuler les attributs

Jusqu'ici, nous avons observé que les attributs auront des valeurs redéfinissables pour chaque objet. Mais qu'en est-il si l'on souhaite avoir une valeur partagée entre plusieurs instances ou à l'inverse gagner un peu en définissant spécifiquement les valeurs pour une instance.

Attribut de classe

Nous avons manqué un peu de précision en définissant précédemment les attributs. Nous avons présenté notre attribut essai de la même façon alors qu'il est apparu dans deux contextes différents : celui de la racine de la classe, et celui de la méthode. Nous avons mentionné que cet attribut était lié à l'instance, ce qui n'est pas pas tout à fait juste. Prenons le point suivi pour aborder le sujet : si à l'inverse, nous souhaitions que la même valeur soit partagée par plusieurs instances, la syntaxe de l'attribut devrait être un peu différente : on le définira en début de classe en dehors de toute méthode ou on le préfixera avec le nom de la classe de manière que l'attribut y soit explicitement associé, et non pas aux instances :

class MaClasse :
      essai = "ok"
      def affiche(self):
                print essai

objet = MaClasse()
objet2 = MaClasse()
objet.affiche()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 4, in affiche
NameError: global name 'essai' is not defined
  

On voit dans cet exemple qu'un petit problème se pose : il n'est pas possible d'accéder à l'attribut essai à partir de la méthode affichée. La première solution qui pourrait nous venir à l'esprit serait d'utiliser le mot clé self pour spécifier l'appartenance de l'attribut, mais voici :

class MaClasse :
     essai = "ok"
     def affiche(self):
             print self.essai

objet = MaClasse()
objet.affiche()
> ok

objet2 = MaClasse()
objet2.affiche()
> ok

objet2.essai = "wow"
objet2.affiche()
> wow

objet.affiche()
> ok
  

Nous nous retrouvons alors dans la même configuration que précédemment et ne résolvons pas notre problème : l'attribut est associé à l'instance, et n'est pas partagé entre celle-ci.
La solution consiste à associer explicitement l'attribut à la classe en le pointant comme tel. Au lieu d'utiliser le mot-clé self, nous utiliserons alors le nom de la classe pour bien préciser que c'est à son niveau que les opérations vont s'effectuer.

>>> class MaClasse:
     def __init__(self):
             MaClasse.essai = "ok"

objet = MaClasse()
objet2 = MaClasse()
print objet.essai
> ok

print objet2.essai
> ok

print MaClasse.essai
> ok

MaClasse.essai = "wow"
print objet.essai
> wow

print objet2.essai
> wow
  

Ici, les deux instances partagent donc bien le même attribut et changer la valeur de cet attribut en la préfixant du nom de la classe, même au moment de la réaffectation, permet bien de spécifier que ce n'est pas au niveau de l'instance que les choses se jouent et que par conséquent, toutes les instances hériteront de cette nouvelle valeur.
Si les choses ne sont pas clairement définies, il est possible de se retrouver avec de petites surprises. Continuons dans la foulée des lignes précédentes :

class MaClasse :
     essai = "ok"
     def affiche(self):
             print self.essai

objet = MaClasse()
objet.affiche()
> ok

objet2 = MaClasse()
objet2.affiche()
> ok

objet2.essai = "wow"
objet2.affiche()
> wow

objet.affiche()
> ok

print objet2.essai
> wow

MaClasse.essai = "test"
objet.affiche()
> test

objet2.affiche()
> wow
 

Il y a une erreur de communication avec le serveur Booktype. Nous ne savons pas actuellement où est le problème.

Vous devriez rafraîchir la page.