À quoi sert le paramètre self en Python ?

self est le nom du paramètre qui correspond à l'instance depuis laquelle la méthode est appelée dans la programmation orientée objet.

Le nom de ce paramètre est une convention. On pourrait l'appeler toto, i ou encore patrick.

Prenons l'exemple d'une classe très simple représentant une voiture :

class Voiture:
    def __init__(self, marque, vitesse, prix):
        self.marque = marque
        self.vitesse = vitesse
        self.prix = prix

mercedes = Voiture(marque="Mercedes", vitesse=200, prix=90000)
print(mercedes)

Dans le code ci-dessus, self correspond à l'instance mercedes lorsque l'objet est instancié.

Dans la méthode __init__, qui est appelée lors de la création de l'instance mercedes, self représente donc notre instance mercedes.

Quand on indique self.vitesse = vitesse, c'est comme si on indiquait mercedes.vitesse = vitesse.

Pour cette raison, on peut, hors de la classe, accéder à l'attribut vitesse qui a été créé sur l'objet mercedes :

class Voiture:
    def __init__(self, marque, vitesse, prix):
        self.marque = marque
        self.vitesse = vitesse
        self.prix = prix

mercedes = Voiture(marque="Mercedes", vitesse=200, prix=90000)
print(mercedes.vitesse)

Ce paramètre self doit absolument figurer en premier dans les méthodes qui composent une classe.

C'est grâce à ce paramètre que l'on va pouvoir accéder à notre instance.

Imaginons une méthode afficher_prix qui nous permette d'afficher le prix de la voiture :

class Voiture:
    def __init__(self, marque, vitesse, prix):
        self.marque = marque
        self.vitesse = vitesse
        self.prix = prix

    def afficher_prix(self):
        print("Le prix de la voiture est de", self.prix, "euros")

mercedes = Voiture(marque="Mercedes", vitesse=200, prix=90000)
mercedes.afficher_prix()

Si vous omettez de mettre le paramètre self dans la méthode afficher_prix, Python vous retournera l'erreur suivante :

TypeError: afficher_prix() takes exactly 0 arguments (1 given) on line 11

Pourquoi Python nous indique-t-il que la méthode afficher_prix reçoit 1 argument (1 given) alors que quand nous appelons la méthode afficher_prix, nous n'envoyons aucun objet entre les parenthèses ?

Ce que vous ne voyez pas, c'est qu'en arrière-plan, Python utilise la classe pour appeler la méthode et envoi l'instance en argument :

class Voiture:
    def __init__(self, marque, vitesse, prix):
        self.marque = marque
        self.vitesse = vitesse
        self.prix = prix

    def afficher_prix(self):
        print("Le prix de la voiture est de", self.prix, "euros")

mercedes = Voiture(marque="Mercedes", vitesse=200, prix=90000)
# Quand on fait ceci :
mercedes.afficher_prix()
# En fait, Python fait ceci :
Voiture.afficher_prix(mercedes)

On voit bien ci-dessus que le paramètre self reçoit bien l'instance mercedes.

Cette opération est réalisée automatiquement par Python lorsque l'on appelle une méthode directement sur une instance (mercedes.afficher_prix() par exemple).

C'est pour cette raison qu'on est obligé de mettre self comme premier paramètre dans les méthodes qui composent une classe.