8249 votes

Que fait if __name__ == "__main__": ?

Que fait cela, et pourquoi devrait-on inclure l'instruction if ?

if __name__ == "__main__":
    print("Bonjour, le Monde!")

Si vous essayez de fermer une question où quelqu'un devrait utiliser cet idiome et ne le fait pas, envisagez de la fermer comme un doublon de<a href="https://stackoverflow.com/questions/6523791">Pourquoi Python exécute-t-il mon module lorsque je l'importe, et comment l'arrêter?</a> à la place. Pour les questions où quelqu'un n'a tout simplement pas appelé de fonctions, ou s'attend incorrectement à ce qu'une fonction nommée <code>main</code> soit utilisée automatiquement comme point d'entrée, utilisez <a href="https://stackoverflow.com/questions/17257631">Pourquoi la fonction main() ne s'exécute-t-elle pas lorsque je lance un script Python? Où le script commence-t-il à s'exécuter?</a>.

43 votes

Juste pour information - qu'est-ce que "main": docs.python.org/3/reference/… et qu'est-ce que "name": docs.python.org/3/reference/…

22 votes

Combien d'entre vous sont venus ici parce que vous voulez copier-coller 'if __name__ == "__main__":'? :-P

5 votes

Il est utile si vous voulez écrire du code Python qui est destiné à être "importé" mais qui peut également être exécuté en tant que script shell autonome. Le code protégé par la vérification if __name__ ne s'exécute que lorsqu'il est invoqué en tant que commande, pas lorsqu'il est importé. C'est aussi utile si vous voulez déboguer un script Python en utilisant une session Python interactive. Vous pouvez "importer" du code qui est normalement exécuté en tant que commande dans une session interactive, puis saisir manuellement du code pour exécuter des fonctions/classes dans le script comme vous le souhaitez.

8856voto

Mr Fooz Points 21092

Étendre un peu sur les Harley de réponse...

Lorsque l'interpréteur Python lit un fichier source, il exécute tout le code qui s'y trouvent. Avant d'exécuter le code, il permettra de définir quelques variables spéciales. Par exemple, si l'interpréteur python est en cours d'exécution que le module (fichier source) que le programme principal, il définit la spéciale __name__ variable pour avoir une valeur en "__main__". Si ce fichier est importé à partir d'un autre module, __name__ sera définie dans le module du même nom.

Dans le cas de votre script, supposons que c'est l'exécution de la fonction principale, par exemple, vous avez dit quelque chose comme

python threading_example.py

sur la ligne de commande. Après avoir défini les variables spéciales, il va exécuter l' import déclaration et charger les modules. Il évaluera ensuite l' def bloc, la création d'un objet de fonction et de créer une variable nommée myfunction qui pointe vers la fonction de l'objet. Il sera alors lire l' if déclaration et de voir qu' __name__ ne l'égalité des "__main__", donc il va exécuter le bloc indiqués.

L'une des raisons pour cela est que, parfois, vous écrivez un module ( .py le fichier) où il peut être exécuté directement. Alternativement, il peut également être importés et utilisés dans un autre module. En faisant le principal de la vérification, vous pouvez avoir que le code s'exécute uniquement lorsque vous souhaitez exécuter le module d'un programme et de ne pas exécuter lorsque quelqu'un veut juste de l'importation de votre module et appelez votre fonctions elles-mêmes.

Voir cette page pour quelques détails supplémentaires.

52 votes

Par curiosité : Que se passe-t-il si j'exécute subprocess.run('foo_bar.py') dans un script python? Je suppose que foo_bar sera lancé avec __name__ = '__main__' tout comme lorsque je tape foo_bar.py manuellement dans cmd. Est-ce le cas? En tenant compte de la réponse de @MrFooz, il ne devrait y avoir aucun problème à le faire et à avoir autant de modules "main" en même temps que je le souhaite. Même le changement de la valeur de __name__ ou avoir plusieurs instances créées de manière indépendante (ou des instances se créant mutuellement par subprocess) interagir les unes avec les autres devraient être monnaie courante pour Python. Est-ce que j'oublie quelque chose ?

41 votes

@hajef Vous avez raison sur le fonctionnement de subprocess.run. Cela dit, une meilleure façon de partager du code entre les scripts est de créer des modules et d'avoir les scripts appeler les modules partagés au lieu de s'inviter mutuellement en tant que scripts. Il est difficile de déboguer les appels subprocess.run car la plupart des débogueurs ne franchissent pas les limites des processus, cela peut ajouter une surcharge système non négligeable pour créer et détruire des processus supplémentaires, etc.

12 votes

J'ai un doute dans l'exemple foo2.py dans la section "food for thought". Que fait "from foo2.py import functionB" ? À mon avis, cela importe simplement foo2.py depuis functionB

2188voto

Adam Rosenfield Points 176408

Lorsque votre script est exécuté en le transmettant comme une commande à l'interpréteur Python,

python myscript.py

tout le code qui est au niveau d'indentation 0 est exécuté. Les fonctions et les classes qui sont définies sont, eh bien, définies, mais aucun de leur code n'est exécuté. Contrairement à d'autres langages, il n'y a pas de fonction main() qui est exécutée automatiquement - la fonction main() est implicitement tout le code au niveau supérieur.

Dans ce cas, le code au niveau supérieur est un bloc if. __name__ est une variable intégrée qui évalue au nom du module actuel. Cependant, si un module est exécuté directement (comme dans myscript.py ci-dessus), alors __name__ est réglé sur la chaîne "__main__". Ainsi, vous pouvez tester si votre script est exécuté directement ou importé par quelque chose d'autre en testant

if __name__ == "__main__":
    ...

Si votre script est importé dans un autre module, ses différentes définitions de fonctions et de classes seront importées et son code de niveau supérieur sera exécuté, mais le code dans le bloc if ci-dessus ne sera pas exécuté car la condition n'est pas remplie. À titre d'exemple de base, considérez les deux scripts suivants :

# fichier one.py
def func():
    print("func() dans one.py")

print("au niveau supérieur dans one.py")

if __name__ == "__main__":
    print("one.py est exécuté directement")
else:
    print("one.py est importé dans un autre module")

# fichier two.py
import one

print("au niveau supérieur dans two.py")
one.func()

if __name__ == "__main__":
    print("two.py est exécuté directement")
else:
    print("two.py est importé dans un autre module")

Maintenant, si vous invoquez l'interpréteur comme

python one.py

La sortie sera

au niveau supérieur dans one.py
one.py est exécuté directement

Si vous exécutez plutôt two.py :

python two.py

Vous obtenez

au niveau supérieur dans one.py
one.py est importé dans un autre module
au niveau supérieur dans two.py
func() dans one.py
two.py est exécuté directement

Ainsi, lorsque le module one est chargé, son __name__ est égal à "one" au lieu de "__main__".

22 votes

Donc, si __name__ == "__main__": vérifie essentiellement si vous exécutez votre script python lui-même, et non pas en train de l'importer ou quelque chose d'autre?

0 votes

@Adam Rosenfield Si votre script est importé dans un autre module, ses différentes fonctions et définitions de classe seront importées et son code de niveau supérieur sera exécuté.... Qu'est-ce que le code de niveau supérieur? Le code avec une indentation de zéro?

889voto

pi. Points 6026

Créez les deux fichiers suivants :

# a.py

import b

# b.py

print("__name__ equals " + __name__)

if __name__ == '__main__':
    print("if-statement was executed")

Exécutez maintenant chaque fichier individuellement.


Exécution de python a.py :

$ python a.py
__name__ equals b

Lorsque a.py est exécuté, il importe le module b. Cela fait que tout le code à l'intérieur de b s'exécute. Python définit globals()['__name__'] dans le module b avec le nom du module, b.

Exécution de python b.py :

$ python b.py
__name__ equals __main__
if-statement was executed

Lorsque seul le fichier b.py est exécuté, Python définit globals()['__name__'] dans ce fichier à "__main__". Par conséquent, l'instruction if s'évalue à True cette fois-ci.

621voto

Aaron Hall Points 7381

Que fait if __name__ == "__main__": ?

Pour résumer les bases :

  • La variable globale __name__ dans le module qui est le point d'entrée de votre programme est '__main__'. Sinon, c'est le nom par lequel vous importez le module.

  • Ainsi, le code sous le bloc if ne s'exécutera que si le module est le point d'entrée de votre programme.

  • Cela permet au code du module d'être importable par d'autres modules sans exécuter le bloc de code en dessous à l'importation.


Pourquoi avons-nous besoin de cela ?

Développement et test de votre code

Disons que vous écrivez un script Python conçu pour être utilisé comme un module :

def do_important():
    """Cette fonction fait quelque chose de très important"""

Vous pourriez tester le module en ajoutant cet appel de fonction à la fin :

do_important()

et en l'exécutant (dans une invite de commande) avec quelque chose comme :

~$ python important.py

Le problème

Cependant, si vous voulez importer le module dans un autre script :

import important

Lors de l'importation, la fonction do_important serait appelée, donc vous auriez probablement commenté votre appel de fonction, do_important(), en bas.

# do_important() # Je dois me rappeler de décommenter pour exécuter ceci!

Et vous devrez alors vous rappeler si vous avez commenté ou non votre appel de la fonction de test. Et cette complexité supplémentaire signifierait que vous êtes susceptible d'oublier, rendant votre processus de développement plus difficile.

Une meilleure façon

La variable __name__ pointe vers l'espace de noms où l'interpréteur Python se trouve à ce moment.

À l'intérieur d'un module importé, c'est le nom de ce module.

Mais à l'intérieur du module principal (ou d'une session interactive Python, c'est-à-dire la boucle de lecture, d'évaluation, d'impression ou REPL de l'interpréteur), vous exécutez tout depuis son "__main__".

Donc si vous vérifiez avant d'exécuter :

if __name__ == "__main__":
    do_important()

Avec ce qui précède, votre code ne s'exécutera que lorsque vous l'exécutez en tant que module principal (ou l'appelez intentionnellement depuis un autre script).

Une façon encore meilleure

Il y a une manière plus pythonique d'améliorer cela cependant.

Et si nous voulons exécuter ce processus métier depuis l'extérieur du module ?

Si nous mettons le code que nous voulons exécuter lors du développement et du test dans une fonction comme ceci, et ensuite effectuons notre vérification pour '__main__' immédiatement après :

def main():
    """logique métier pour l'exécution de ce module en tant que principal !"""
    setup()
    foo = do_important()
    bar = do_even_more_important(foo)
    for baz in bar:
        do_super_important(baz)
    teardown()

# Voici notre idiome de paiement !
if __name__ == '__main__':
    main()

Nous avons maintenant une fonction finale pour la fin de notre module qui s'exécutera si nous exécutons le module en tant que module principal.

Cela permettra au module et à ses fonctions et classes d'être importés dans d'autres scripts sans exécuter la fonction main, et permettra également d'appeler le module (et ses fonctions et classes) lors de l'exécution à partir d'un autre module '__main__', c'est-à-dire

import important
important.main()

Cet idiome se trouve également dans la documentation Python dans une explication du module __main__. Ce texte déclare :

Ce module représente la portée (autrement anonyme) dans laquelle le programme principal de l'interpréteur s'exécute - commandes lues soit à partir de l'entrée standard, depuis un fichier de script, ou depuis une invite interactive. C'est cet environnement dans lequel le strophe idiomatique "script conditionnel" fait exécuter un script :

if __name__ == '__main__':
    main()

0 votes

Désolé, il ne peut y avoir aucune différence entre la méthode mentionnée dans la section intitulée Une meilleure façon et la méthode mentionnée dans la section intitulée Une encore meilleure façon. Pourriez-vous s'il vous plaît le souligner?

0 votes

@John Je ne pense pas qu'il y ait de différence. Il a utilisé A Better Way pour illustrer comment nous pouvons exécuter le module en tant que script et An Even Better Way pour illustrer comment nous pouvons importer le module ailleurs et l'exécuter.

182voto

Harley Holcombe Points 34618

if __name__ == "__main__" est la partie qui s'exécute lorsque le script est exécuté depuis (disons) la ligne de commande en utilisant une commande comme python myscript.py.

7 votes

Pourquoi un fichier helloworld.py avec juste print("hello world") en lui peut s'exécuter avec la commande python helloworld.py même s'il n'y a pas de if __name__ == "__main__"?

7 votes

Lorsque vous exécutez python helloworld.py, il exécutera l'intégralité du fichier script (que vous spécifiiez if __name__ == "__main__" ou non). Il n'y a qu'une différence d'exécution lorsque vous importez helloworld.py depuis un autre script. Dans ce cas, le bloc de code if __name__ == "__main__" ne s'exécute pas du tout.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X