__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é.

1er cas de figure - Le script est 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__)
#norun
$ python3 /Users/Docstring/script.py
"__main__"

2e cas de figure - Le script est 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 :

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

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

#norun
>>> 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 script Python, comme la fonction convert_image :

#norun
# /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) :

#norun
$ 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 :

#norun
# /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()