Cursus
Le bloc conditionnel qui commence par if __name__ == "__main__" revient souvent dans le code Python. Cette ligne peut sembler cryptique, et beaucoup de débutants l'utilisent sans vraiment savoir à quoi elle sert ni s'ils devraient l'utiliser. Les développeurs venant d'autres langages peuvent également la mal comprendre et en abuser.
Ce tutoriel explique en profondeur la signification de l'idiome Python if__name__ == "__main__" et montre comment et quand l'utiliser.
Devenez ingénieur en données
Comprendre __name__ et "__main__"
L'idiome if __name__ == "__main__" est une instruction if qui vérifie une égalité.
Le premier opérande, à gauche de l'opérateur d'égalité ==, est l'attribut __name__. Les noms Python qui commencent et finissent par un double soulignement sont des identifiants spéciaux. Chaque module possède un attribut __name__. Python définit cette variable au nom du module, que le système d'import de Python utilise pour identifier chaque module de manière unique.
Toutefois, si le module se trouve dans l'environnement de code de haut niveau, c'est-à-dire s'il sert de point d'entrée du programme, Python affecte à l'attribut __name__ la chaîne "__main__".
Voyons quelques exemples. Créons un script appelé exploring_name_main.py :
# exploring_name_main.py
import random
print(__name__)
print(random.__name__)
Vous pouvez exécuter ce script directement avec la commande suivante dans le terminal :
$ python exploring_name_main.py
__main__
random
Le script exploring_name_main.py se trouve dans l'environnement de code de haut niveau puisqu'il constitue le point d'entrée du programme. Par conséquent, la variable __name__ vaut la chaîne "__main__".
En revanche, le module random est importé et ne se trouve pas dans l'environnement de code de haut niveau. Son attribut __name__ correspond donc au nom du module.
Ensuite, créons un nouveau script appelé more_exploration.py, qui importe le premier script :
# more_exploration.py
import exploring_name_main
Lancez ce script avec la commande suivante dans le terminal :
$ python more_exploration.py
exploring_name_main
random
Le code d'un module est exécuté lorsque le module est importé. Ainsi, en exécutant more_exploration.py, le programme affiche la sortie des deux appels à print() dans exploring_name_main.py. Comme exploring_name_main.py n'est plus le point d'entrée du programme, son attribut __name__ prend le nom du script au lieu de "__main__".
Le bloc conditionnel if __name__ == "__main__"
La variable __name__ permet de savoir si un module est le point d'entrée principal d'un programme. Un module peut donc contenir du code qui ne s'exécutera que lorsqu'il est lancé directement comme script, et non lorsqu'il est importé. Tout code devant s'exécuter uniquement lorsque le script est lancé directement se place dans le bloc conditionnel if __name__ == "__main__" :
# exploring_name_main.py
import random
print(__name__)
print(random.__name__)
number = random.randint(1, 10)
if __name__ == "__main__":
print("This script is in the top-level code environment")
print(f"The number is {number}")
Le code de exploring_name_main.py comprend maintenant un bloc conditionnel if __name__ == "__main__". Voyons si cela change quelque chose à l'exécution :
$ python exploring_name_main.py
__main__
random
This script is in the top-level code environment
The number is 10
Lorsque le script est exécuté directement, la variable __name__ vaut la chaîne "__main__". La condition du if est donc évaluée à True, et Python exécute le code situé dans le bloc if.
En revanche, quand le module est importé, __name__ prend le nom du module et le programme n'exécute pas le bloc if. Rappel : le script more_exploration.py importe exploring_name_main :
$ python more_exploration.py
exploring_name_main
random
Le programme n'appelle pas les fonctions print() dans exploring_name_main.py. Elles se trouvent dans le bloc conditionnel qui n'est pas exécuté puisque __name__ n'est pas égal à "__main__".
Bonnes pratiques et conseils pour utiliser if __name__ == "__main__" en Python
L'idiome if __name__ == "__main__" s'utilise lorsque du code ne doit s'exécuter que si un fichier est lancé comme script, et non lorsqu'il est importé comme module. La différence entre les termes script et module tient uniquement à la façon d'utiliser le fichier. Dans les deux cas, il s'agit de fichiers portant l'extension .py.
Un cas d'usage fréquent : un script définit des variables, fonctions et classes susceptibles d'être réutilisées dans d'autres programmes. Voici un exemple avec un script nommé shapes.py :
# shapes.py
import math
def find_area_of_circle(radius):
return math.pi * radius ** 2
def find_area_of_rectangle(width, height):
return width * height
if __name__ == "__main__":
shape = int(input("Enter 1 for circle, 2 for rectangle: "))
if shape == 1:
radius = int(input("Enter radius: "))
print(f"The area of the circle is {find_area_of_circle(radius)}")
elif shape == 2:
width = int(input("Enter width: "))
height = int(input("Enter height: "))
print(f"The area of the rectangle is {find_area_of_rectangle(width, height)}")
Enter 1 for circle, 2 for rectangle: 2
Enter width: 10
Enter height: 20
The area of the rectangle is 200
Ce code n'a pas besoin de l'idiome if __name__ == "__main__" si l'intention est toujours de l'exécuter comme script. En revanche, l'ajout de cette condition permet d'importer le code comme module sans exécuter les lignes du bloc if. Considérons un autre script appelé more_shapes.py :
# more_shapes.py
import shapes
radius = 5
print(f"The area of the circle defined in 'more_shapes.py' is: "
f"{shapes.find_area_of_circle(radius)}")
The area of the circle defined in 'more_shapes.py' is: 78.53981633974483
Ce nouveau script, more_shapes.py, a accès aux fonctions définies dans shapes.py grâce à l'instruction d'import. Cependant, le code du bloc if __name__ == "__main__" dans shapes.py n'est pas exécuté. Sans l'instruction if dans shapes.py, tout le code s'exécuterait lors de l'import du module.
Utiliser le bloc if __name__ == "__main__" pour gérer des saisies utilisateur est un cas d'usage courant. Les entrées utilisateur sont ignorées si le fichier est importé comme module, mais prises en compte lorsqu'il est exécuté directement en tant que code de haut niveau.
Utiliser une fonction main()
Bonne pratique : limitez autant que possible le nombre d'instructions dans le bloc if __name__ == "__main__" pour améliorer la lisibilité. Pour cela, on définit généralement une fonction, appelée dans le bloc conditionnel. On la nomme souvent main(), mais tout autre nom convient :
# shapes.py
import math
def find_area_of_circle(radius):
return math.pi * radius ** 2
def find_area_of_rectangle(width, height):
return width * height
def main():
shape = int(input("Enter 1 for circle, 2 for rectangle: "))
if shape == 1:
radius = int(input("Enter radius: "))
print(f"The area of the circle is {find_area_of_circle(radius)}")
elif shape == 2:
width = int(input("Enter width: "))
height = int(input("Enter height: "))
print(f"The area of the rectangle is {find_area_of_rectangle(width, height)}")
if __name__ == "__main__":
main()
Le contenu de la fonction main() est identique à celui présent auparavant directement dans le bloc if __name__ == "__main__".
En Python, la fonction main() n'est pas requise en tant que point d'entrée du programme, contrairement à certains autres langages. L'utilisation de main() et de l'idiome if __name__ == "__main__" est donc optionnelle, et n'est utile que si le code doit servir à la fois de script autonome et de module.
Un autre cas d'usage fréquent de if __name__ == "__main__" en Python consiste à ajouter des tests au script. Les tests s'exécutent lorsque le script est lancé directement, mais pas lorsqu'il est importé depuis un autre module. Cela convient pour des cas simples, mais il est préférable de placer les tests dans un module séparé dédié aux tests.
Conclusion
En Python, if __name__ == "__main__" est utile pour inclure du code exécuté uniquement lorsqu'un script est lancé directement, et non lorsqu'il est importé. L'interpréteur Python affecte à la variable __name__ le nom du module s'il est importé, et la chaîne "__main__" si le module est le point d'entrée principal du programme.
Contrairement à certains autres langages, la fonction main() et l'idiome if __name__ == "__main__" ne sont pas requis pour exécuter du code Python ; ce sont des outils dont vous pouvez vous servir quand c'est pertinent.
Devenez ingénieur en données
J'ai étudié la physique et les mathématiques au niveau UG à l'université de Malte. J'ai ensuite déménagé à Londres et obtenu un doctorat en physique à l'Imperial College. J'ai travaillé sur de nouvelles techniques optiques pour obtenir des images de la rétine humaine. Aujourd'hui, je me concentre sur l'écriture, la communication et l'enseignement de Python.
