À quoi sert la fonction super en Python ?

La fonction super est généralement utilisée pour obtenir la classe parente sans avoir besoin de la nommer explicitement.

On l'utilise donc généralement pour faire de la délégation, notamment à l'intérieur de la méthode __init__ dans le cas d'une classe qui hérite d'une autre classe :

class Employee:
    def __init__(self, name, surname):
        self.name = name
        self.surname = surname

class Boss(Employee):
    def __init__(self, name, surname):
        # Sans super
        # Employee.__init__(self, name=name, surname=surname)
        super().__init__(name=name, surname=surname)
        self.big_boss = True


boss = Boss(name="John", surname="Smith")
print(boss.name, boss.surname)
Un instant

On utilise ici super pour ne pas avoir à écrire explicitement le nom de la classe dont Boss hérite (ici, Employee).

La ligne :

Employee.__init__(self, name=name, surname=surname)

Est donc équivalente à :

super().__init__(name=name, surname=surname)

Avec Python 2, il fallait passer la classe et l'instance à la fonction super (super(Boss, self).__init__(name, surname)) mais ce n'est plus le cas avec Python 3.

À noter que cette fonction peut être utilisée en dehors de la méthode __init__ (et même en dehors d'une fonction ou d'une classe).

Par exemple dans le code ci-dessous, on surcharge la méthode parle de la classe Employee dans la classe Boss pour y ajouter un print.

On utilise la fonction super pour appeler la méthode parle de la classe parente :

class Employee:
    def __init__(self, name, surname):
        self.name = name
        self.surname = surname

    def parle(self):
        print("Je m'appelle", self.name)

class Boss(Employee):
    def __init__(self, name, surname):
        # Sans super
        # Employee.__init__(self, name=name, surname=surname)
        super().__init__(name=name, surname=surname)
        self.big_boss = True

    def parle(self):
        super().parle()  # On pourrait à la place écrire Employee.parle(self)
        print("...et je suis le Boss 😎")

patrick = Employee(name="Patrick", surname="Tremblay")
boss = Boss(name="John", surname="Smith")

patrick.parle()
boss.parle()
Un instant

La fonction super est également utilisée de façon beaucoup plus complexe pour pouvoir manipuler le « MRO » (Method Resolution Order ou « ordre de résolution des méthodes » en français).

Si vous souhaitez en savoir plus sur cette utilisation de la fonction super, je vous recommande la lecture de cet excellent article.

Ancienne syntaxe de la fonction super en Python 2

Dans les versions antérieures de Python, notamment Python 2, l'utilisation de la fonction super nécessitait une syntaxe légèrement différente de celle adoptée en Python 3. Cette ancienne méthode requiert de spécifier explicitement la classe et l'instance lors de l'appel à super, ce qui contrastait avec l'approche plus simplifiée de Python 3.

Exemple d'utilisation :

Considérons les classes Employee et Boss :

class Employee:
    def __init__(self, name, surname):
        self.name = name
        self.surname = surname

class Boss(Employee):
    def __init__(self, name, surname):
        # Ancienne syntaxe de super en Python 2
        super(Boss, self).__init__(name=name, surname=surname)
        self.big_boss = True
Un instant

Dans cet exemple, super(Boss, self) fait référence à la classe parente d'Employee, permettant ainsi d'appeler sa méthode __init__. La nécessité de passer explicitement Boss et self comme arguments à super permettait de clarifier l'intention du code et d'assurer que Python comprenait exactement quel était l'ordre de résolution de méthode (MRO) à utiliser pour la recherche de la méthode parente.

Comparaison avec Python 3 :

En Python 3, la syntaxe de super a été simplifiée. Il n'est plus nécessaire de passer la classe et l'instance comme arguments. Ainsi, l'appel super().__init__(name=name, surname=surname) suffit pour atteindre le même résultat que l'ancienne syntaxe, rendant le code plus propre et moins sujet à erreur si la hiérarchie des classes venait à changer.

Avantages

  • Explicité : La syntaxe explicite de Python 2 rend clair quelles classes sont impliquées dans l'appel de la méthode.

  • Contrôle : Elle offre un contrôle plus précis, particulièrement dans des hiérarchies de classes complexes où le MRO peut ne pas être immédiatement évident.

Inconvénients

  • Verbosité : Plus verbeuse, cette syntaxe peut alourdir le code, surtout dans des structures simples.

  • Rigidité : Modifier la hiérarchie des classes nécessite de revoir tous les appels à super pour s'assurer qu'ils référencent correctement les nouvelles relations de classe.

L'ancienne syntaxe est toujours valide en Python 3, mais elle est généralement déconseillée sauf pour des cas très spécifiques où un contrôle explicite sur l'ordre de résolution des méthodes est nécessaire. Cela peut être utile dans le cas de multiples héritages où l'ordre MRO n'est pas linéaire et peut prêter à confusion.

Bravo, tu es prêt à passer à la suite

Rechercher sur le site

Formulaire de contact

Inscris-toi à Docstring

Pour commencer ton apprentissage.

Tu as déjà un compte ? Connecte-toi.