Détails
Que fait si __name__ == "__main__": ?
Que fait le if __name__ == "__main__":
?
# Threading example
import time, thread
def myfunction(string, sleeptime, lock, *args):
while True:
lock.acquire()
time.sleep(sleeptime)
lock.release()
time.sleep(sleeptime)
if __name__ == "__main__":
lock = thread.allocate_lock()
thread.start_new_thread(myfunction, ("Thread #: 1", 2, lock))
thread.start_new_thread(myfunction, ("Thread #: 2", 2, lock))
5496
3
Lorsque l'interpréteur Python lit un fichier source, il fait deux choses :
il définit quelques variables spéciales comme
__name__
, et ensuiteil exécute tout le code trouvé dans le fichier.
Voyons comment cela fonctionne et comment cela se rapporte à votre question sur les vérifications
__name__
que nous voyons toujours dans les scripts Python.Exemple de code
Utilisons un exemple de code légèrement différent pour explorer le fonctionnement des importations et des scripts. Supposons que ce qui suit se trouve dans un fichier appelé
foo.py
.Variables spéciales
Lorsque l'interpréteur Python lit un fichier source, il définit d'abord quelques variables spéciales. Dans ce cas, nous nous intéressons à la variable
__name__
.Lorsque votre module est le programme principal
Si vous exécutez votre module (le fichier source) en tant que programme principal, par ex.
l'interpréteur assignera la chaîne de caractères codée en dur
"__main__"
à la variable__name__
, soitQuand votre module est importé par un autre
D'un autre côté, supposons qu'un autre module soit le programme principal et qu'il importe votre module. Cela signifie qu'il y a une déclaration comme celle-ci dans le programme principal, ou dans un autre module que le programme principal importe :
Dans ce cas, l'interpréteur regardera le nom de fichier de votre module,
foo.py
, enlèvera le.py
, et assignera cette chaîne à la variable__name__
de votre module, soitExécution du code du module
Après avoir configuré les variables spéciales, l'interpréteur exécute tout le code du module, une instruction à la fois. Il se peut que vous souhaitiez ouvrir une autre fenêtre du côté de l'échantillon de code afin de pouvoir suivre cette explication.
Toujours
Il imprime la chaîne "before import" (sans les guillemets).
Elle charge le module
math
et l'assigne à une variable appeléemath
. Cela revient à remplacerimport math
par ce qui suit (notez que__import__
est une fonction de bas niveau en Python qui prend une chaîne de caractères et déclenche l'importation réelle) :Il imprime la chaîne
"avant la fonctionA"
.Il exécute le bloc
def
, en créant un objet fonction, puis en assignant cet objet fonction à une variable appeléefunctionA
.Il imprime la chaîne
"before functionB"
.Il exécute le deuxième bloc
def
, en créant un autre objet fonction, puis en l'assignant à une variable appeléefunctionB
.Elle imprime la chaîne
"before __name__ guard"
.Uniquement lorsque votre module est le programme principal
__name__
a bien été défini comme"__main__"
et il appelle les deux fonctions, en imprimant les chaînes"Function A"
et"Function B 10.0"
.Uniquement lorsque votre module est importé par un autre
__name__
sera"foo"
, et non"__main__"
, et il sautera le corps de l'instructionif
.Toujours
"after __name__ guard"
dans les deux situations.***Il n'y a pas de problème.
En résumé, voici ce qui serait imprimé dans les deux cas :
Pourquoi ça marche comme ça ?
Vous pouvez naturellement vous demander pourquoi quelqu'un voudrait ceci. Eh bien, parfois vous voulez écrire un fichier
.py
qui peut être à la fois utilisé par d'autres programmes et/ou modules en tant que module, et qui peut aussi être exécuté en tant que programme principal lui-même. Exemples :Votre module est une bibliothèque, mais vous voulez avoir un mode script où il exécute des tests unitaires ou une démo.
Votre module est seulement utilisé comme programme principal, mais il a quelques tests unitaires, et le cadre de test fonctionne en important des fichiers
.py
comme votre script et en exécutant des fonctions de test spéciales. Vous ne voulez pas qu'il essaie d'exécuter le script juste parce qu'il importe le module.Votre module est principalement utilisé comme programme principal, mais il fournit également une API conviviale pour les utilisateurs avancés.
Au-delà de ces exemples, il est élégant de constater que l'exécution d'un script en Python consiste simplement à configurer quelques variables magiques et à importer le script. "L'exécution du script est un effet secondaire de l'importation du module du script.
Matière à réflexion
Question : Puis-je avoir plusieurs blocs de vérification
__name__
? Réponse : c'est étrange de le faire, mais le langage ne vous en empêchera pas.Supposons que ce qui suit se trouve dans
foo2.py
. Que se passe-t-il si vous ditespython foo2.py
sur la ligne de commande ? Pourquoi ?__name__
dansfoo3.py
:Lorsque votre script est exécuté en le passant comme une commande à l'interpréteur Python,
tout le code qui est au niveau d'indentation 0 est exécuté. Les fonctions et les classes qui sont définies sont définies, mais aucun de leurs codes n'est exécuté. Contrairement aux autres langages, il n'y a pas de fonction
main()
qui s'exécute automatiquement - la fonctionmain()
est implicitement tout le code du niveau supérieur.Dans ce cas, le code de haut niveau est un bloc
if
.__name__
est une variable intégrée qui correspond au nom du module courant. Cependant, si un module est exécuté directement (comme dansmyscript.py
ci-dessus), alors__name__
prend la valeur de la chaîne"__main__"
. Ainsi, vous pouvez vérifier si votre script est exécuté directement ou s'il est importé par quelque chose d'autre en testantSi votre script est importé dans un autre module, ses diverses définitions de fonctions et de classes seront importées et son code de haut niveau sera exécuté, mais le code dans le corps then de la clause
if
ci-dessus ne sera pas exécuté car la condition n'est pas remplie. Comme exemple de base, considérons les deux scripts suivants :Maintenant, si vous invoquez l'interpréteur en tant que
La sortie sera
Si vous exécutez
two.py
à la place :Vous obtenez
Ainsi, lorsque le module
one
est chargé, son__name__
est égal à"one"
au lieu de"__main__"
.if __name__ == "__main__"
est la partie qui s'exécute lorsque le script est lancé depuis (disons) la ligne de commande en utilisant une commande commepython myscript.py
.