À quoi sert la variable __name__ ?

La variable __name__ est une variable spéciale de Python dont la valeur est automatiquement déterminée en fonction de la façon dont un script est exécuté.

Avec un script exécuté directement

Si vous exécutez le script python directement la variable __name__ contiendra la chaîne de caractères "__main__".

Pour vérifier par vous-même, vous pouvez ajouter la ligne print(__name__) dans un fichier python et l'exécuter depuis le terminal comme ceci :

# /Users/Docstring/script.py
print(__name__)

En exécutant le script dans un terminal :

$ python3 script.py
"__main__"

Dans un script importé

Si vous importez le script en tant que module, la variable __name__ sera égale au nom du module.

Reprenons le même script Python suivant :

# /Users/Docstring/script.py
print(__name__)

Dans un interpréteur Python, j'importe ce script :

>>> import script
"script"

Dans quel cas utiliser la variable __name__ ?

On utilise souvent cette variable à l'intérieur de la structure conditionnelle suivante :

"""Module de test"""

def foo():
    """Fonction de test"""
    pass

if __name__ == "__main__":
    print("Ce code ne sera exécuté que si le script Python est exécuté directement.")
    print("Si le module est importé, ce code ne sera pas exécuté car la variable __name__ ne sera pas égale à '__main__' mais au nom du module (donc du fichier python).")

On pourrait imaginer par exemple un module Python qui permette de convertir des images d'un format à un autre.

Ce module contient des fonctions que l'on peut utiliser dans d'autres scripts Python, comme la fonction convert_image :

# /Users/Docstring/convert_utilities.py
"""Fonctions pour convertir des images"""

import sys

def convert_image(source, format="PNG"):
    """Cette fonction convertie le fichier envoyé au paramètre source au format indiqué par le paramètre format."""
    pass

if __name__ == "__main__":
    image_path = sys.argv[-2]
    format = sys.argv[-1]
    convert_image(source=image_path, format=format)

On pourrait utiliser ce script directement dans un terminal en indiquant des valeurs qui seront récupérées par le module sys (grâce à sys.argv) :

$ python3 /Users/Docstring/convert_utilities.py "/Users/Docstring/Images/vacances.jpg" "JPG"

En exécutant directement le script comme ci-dessus, la variable __name__ sera égale à __main__.

Le code à l'intérieur de la structure conditionnelle sera donc exécuté. Ce code va récupérer le chemin de l'image ainsi que le format et opérer la conversion.

Mais ce fichier convert_utilities pourrait également être importé dans un autre programme.

Dans ce cas-ci, on ne souhaite pas que le script essaie de récupérer les données envoyées à sys.argv.

Grâce à la structure conditionnelle if __name__ == "__main__", le code ne sera pas exécuté, car dans le cas d'un import, la condition sera fausse (car __name__ sera égal au nom du module, donc à la chaîne de caractère "convert_utilities").

On peut donc importer le module sans problème :

# /Users/Docstring/app_convertisseur_images.py
"""Application avec interface graphique pour convertir des images"""

import convert_utilities

class App():
    def button_clicked(self):
        """Commence la conversion des images"""
        convert_utilities.convert_image()