Attributs et instances de classe#
Rappels#
Voici un exemple de classe qui contient une méthode :
class MaClasse
    def ma_méthode(self):
        print(self.mon_attribut)
Le bloc indenté en-dessous du mot-clé class s’appelle le
corps de la classe. Et les méthodes sont définies avec le
mot-clé def dans le corps de la classe.
On dit que ce sont des méthodes d’instance parce qu’il faut créer une instance pour pouvoir les appeler :
mon_instance = MaClasse()
mon_instance.ma_méthode()
Attributs de classes#
On peut également déclarer des variables dans le corps d’une classe.
On crée ainsi des attributs de classe :
class MaClasse:
    mon_attribut_de_classe = 42
Ici mon_attribut_de_classe existe à la fois dans les instances de MaClasse
et dans la classe elle-même :
print(MaClasse.mon_attribut_de_classe)
# affiche: 42
mon_instance = MaClasse()
print(mon_instance.mon_attribut_de_classe)
# affiche: 42
Un point important est que les attributs de classe sont partagés entre toutes les instances. Voici un exemple d’utilisation possible :
class Voiture:
    nombre_total_de_voitures_fabriquées = 0
    def __init__(self, marque, couleur):
        print("Construction d'une", marque, couleur)
        Voiture.nombre_total_de_voitures_fabriquées += 1
ferrari_1 = Voiture("Ferrari", "rouge")
mercedes_1  = Voiture("Mercedes, "noire")
ferrari_2 = Voiture("Ferrari", "rouge")
print("total:", Voiture.nombre_total_de_voitures_fabriquées)
# affiche:
# Construction d'une Ferrari rouge
# Construction d'une Mercedes noire
# Construction d'une Ferrari rouge
# total: 3
Notez que pour changer l’attribut de classe depuis une méthode, (comme dans la
méthode __init__ ci-dessus) on utilise le nom de la classe directement, et
non pas self.
Méthodes de classes#
On peut aussi définir des méthodes de classes avec le décorateur classmethod.
Dans ce cas, le premier argument s’appelle cls et prend la valeur de la classe
elle-même. Pour poursuivre sur notre exemple :
class Voiture:
    nombre_total_de_voitures_fabriquées = 0
    def __init__(self, marque, couleur):
        print("Construction d'une", marque, couleur)
        Voiture.nombre_total_de_voitures_fabriquées += 1
    @classmethod
    def fabrique_ferrari(cls):
        return cls("ferrari", "rouge")
ferrari = Voiture.fabrique_ferrari()
Détaillons ce qu’il se passe sur la dernière ligne :
à gauche du signe égal, il y a une variable, et à droite une expression (Voiture.fabrique_ferrari())
L’expression est constitué d’une classe à gauche du point (Voiture), et
d’un attribut à droite du point fabrique_ferrari, suivi de parenthèses.
Comme fabrique_ferrari est une méthode de classe, on va appeler la méthode
de classe fabrique_ferrari en lui passant la classe courante en argument.
On arrive ainsi dans le corps de la méthode de classe fabrique_ferrari, et
cls vaut la classe Voiture.
Finalement, on évalue l’expression cls("ferrari", rouge") en remplaçant
cls par sa valeur, ce qui donne Voiture("ferrari", "rouge") qui
correspond bien à ce qu’on obtient : Une instance de la classe Voiture.