Que faire si __name__ == “__main__”: faire?


6070

Étant donné le code suivant, 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))

La if __name__ == "__main__":condition de bloc a- t-elle été déconseillée / obsolète jusqu'à Python 3? J'ai trouvé des informations le confirmant.
carloswm85

2
@ carloswm85 Ce n'est pas vrai.
Giorgos Myrianthous

Réponses:


6652

Chaque fois que l'interpréteur Python lit un fichier source, il fait deux choses:

  • il définit quelques variables spéciales comme __name__, puis

  • il exécute tout le code trouvé dans le fichier.

Voyons comment cela fonctionne et comment cela se rapporte à votre question sur les __name__vérifications 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.

# Suppose this is foo.py.

print("before import")
import math

print("before functionA")
def functionA():
    print("Function A")

print("before functionB")
def functionB():
    print("Function B {}".format(math.sqrt(100)))

print("before __name__ guard")
if __name__ == '__main__':
    functionA()
    functionB()
print("after __name__ guard")

Variables spéciales

Lorsque l'interpeter Python lit un fichier source, il définit d'abord quelques variables spéciales. Dans ce cas, nous nous soucions de la __name__variable.

Lorsque votre module est le programme principal

Si vous exécutez votre module (le fichier source) comme programme principal, par exemple

python foo.py

l'interprète affectera la chaîne codée en dur "__main__"à la __name__variable, c'est-à-dire

# It's as if the interpreter inserts this at the top
# of your module when run as the main program.
__name__ = "__main__" 

Lorsque 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, le programme principal importe:

# Suppose this is in some other main program.
import foo

L'interpréteur recherchera votre foo.pyfichier (ainsi que la recherche de quelques autres variantes), et avant d'exécuter ce module, il attribuera le nom "foo"de l'instruction d'importation à la __name__variable, c'est-à-dire

# It's as if the interpreter inserts this at the top
# of your module when it's imported from another module.
__name__ = "foo"

Exécution du code du module

Une fois les variables spéciales configurées, l'interpréteur exécute tout le code du module, une instruction à la fois. Vous souhaiterez peut-être ouvrir une autre fenêtre sur le côté avec l'exemple de code afin de pouvoir suivre cette explication.

Toujours

  1. Il imprime la chaîne "before import"(sans guillemets).

  2. Il charge le mathmodule et l'affecte à une variable appelée math. Cela équivaut à le remplacer import mathpar ce qui suit (notez qu'il __import__s'agit d'une fonction de bas niveau en Python qui prend une chaîne et déclenche l'importation réelle):

# Find and load a module given its string name, "math",
# then assign it to a local variable called math.
math = __import__("math")
  1. Il imprime la chaîne "before functionA".

  2. Il exécute le defbloc, crée un objet fonction, puis affecte cet objet fonction à une variable appelée functionA.

  3. Il imprime la chaîne "before functionB".

  4. Il exécute le deuxième defbloc, crée un autre objet fonction, puis l'affecte à une variable appelée functionB.

  5. Il imprime la chaîne "before __name__ guard".

Uniquement lorsque votre module est le programme principal

  1. Si votre module est le programme principal, il verra qu'il __name__a bien été défini sur "__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

  1. ( À la place ) Si votre module n'est pas le programme principal , mais a été importé par un autre, puis __name__sera "foo", non "__main__", et ça va sauter le corps de la ifdéclaration.

Toujours

  1. Il imprimera la chaîne "after __name__ guard"dans les deux situations.

Sommaire

En résumé, voici ce qui serait imprimé dans les deux cas:

# What gets printed if foo is the main program
before import
before functionA
before functionB
before __name__ guard
Function A
Function B 10.0
after __name__ guard
# What gets printed if foo is imported as a regular module
before import
before functionA
before functionB
before __name__ guard
after __name__ guard

Pourquoi ça marche comme ça?

Vous pourriez naturellement vous demander pourquoi quelqu'un voudrait cela. Eh bien, parfois, vous voulez écrire un .pyfichier qui peut être à la fois utilisé par d'autres programmes et / ou modules en tant que module, et peut également ê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 n'est utilisé que comme programme principal, mais il a quelques tests unitaires, et le framework de test fonctionne en important des .pyfichiers 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 simplement 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 que l'exécution d'un script en Python consiste simplement à configurer quelques variables magiques et à importer le script. "Exécuter" le script est un effet secondaire de l'importation du module du script.

Nourriture pour la pensée

  • Question: Puis-je avoir plusieurs __name__blocs de vérification? Réponse: c'est étrange de le faire, mais la langue ne vous arrêtera pas.

  • Supposons que ce qui suit est dedans foo2.py. Que se passe-t-il si vous dites python foo2.pysur la ligne de commande? Pourquoi?

# Suppose this is foo2.py.

def functionA():
    print("a1")
    from foo2 import functionB
    print("a2")
    functionB()
    print("a3")

def functionB():
    print("b")

print("t1")
if __name__ == "__main__":
    print("m1")
    functionA()
    print("m2")
print("t2")
  • Maintenant, déterminez ce qui se passera si vous supprimez l' __name__enregistrement foo3.py:
# Suppose this is foo3.py.

def functionA():
    print("a1")
    from foo3 import functionB
    print("a2")
    functionB()
    print("a3")

def functionB():
    print("b")

print("t1")
print("m1")
functionA()
print("m2")
print("t2")
  • Qu'est-ce que cela fera lorsqu'il sera utilisé comme script? Une fois importé en tant que module?
# Suppose this is in foo4.py
__name__ = "__main__"

def bar():
    print("bar")

print("before __name__ guard")
if __name__ == "__main__":
    bar()
print("after __name__ guard")

14
Par curiosité: que se passe-t-il si je lance subprocess.run('foo_bar.py')dans un script python? Je suppose que foo_barcela commencera __name__ = '__main__'comme lorsque j'introduis foo_bar.pymanuellement cmd. Est-ce le cas? En tenant compte de la réponse de @MrFooz, cela ne devrait poser aucun problème et avoir autant de modules "principaux" à la fois que je le souhaite. Même la modification de la __name__valeur ou le fait d'avoir plusieurs instances indépendantes (ou des instances qui se sont créées les unes les autres subprocess) interagissent les unes avec les autres devrait être normal pour Python. Dois-je manquer quelque chose?
hajef

12
@hajef Vous avez raison sur la façon dont les choses fonctionneraient subprocess.run. Cela dit, une façon généralement meilleure de partager du code entre des scripts consiste à créer des modules et à faire en sorte que les scripts appellent les modules partagés au lieu de s'appeler mutuellement en tant que scripts. Il est difficile de déboguer les subprocess.runappels car la plupart des débogueurs ne dépassent pas les limites des processus, cela peut ajouter des frais généraux non triviaux pour créer et détruire les processus supplémentaires, etc.
M. Fooz

4
J'ai un doute dans l'exemple de foo2.py dans la section de réflexion. Que fait la fonction d'importation de foo2.py? À mon avis, il importe juste foo2.py de functionB
user471651

1
@MrFooz Je n'ai jamais eu l'intention de faire quelque chose comme ça xD Cela m'est juste venu à l'esprit et je me suis rendu compte que c'était assez suffisant pour peut-être aider ppl. enroulant leurs esprits autour de ce genre de choses. @ user471651 Pourquoi from foo2 import functionBimporter foo2 depuis functionB? C'est une contorsion sémantique. from module import methodimporte la méthode du module.
hajef

2
L'un des modules pouvant importer votre code est multiprocessingnotamment de rendre ce test nécessaire sous Windows.
Yann Vernier

1801

Lorsque votre script est exécuté en le passant sous forme de 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, bien, définies, mais aucun de leur code n'est exécuté. Contrairement à d'autres langages, il n'y a pas de main()fonction qui s'exécute automatiquement - la main()fonction est implicitement tout le code au niveau supérieur.

Dans ce cas, le code de niveau supérieur est un ifbloc. __name__est une variable intégrée qui évalue le nom du module actuel. Cependant, si un module est exécuté directement (comme myscript.pyci-dessus), il __name__est alors défini sur la chaîne "__main__". Ainsi, vous pouvez tester si votre script est exécuté directement ou importé par autre chose 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 corps de la ifclause ci-dessus ne sera pas exécuté car la condition est pas rencontré. Comme exemple de base, considérez les deux scripts suivants:

# file one.py
def func():
    print("func() in one.py")

print("top-level in one.py")

if __name__ == "__main__":
    print("one.py is being run directly")
else:
    print("one.py is being imported into another module")
# file two.py
import one

print("top-level in two.py")
one.func()

if __name__ == "__main__":
    print("two.py is being run directly")
else:
    print("two.py is being imported into another module")

Maintenant, si vous invoquez l'interpréteur comme

python one.py

La sortie sera

top-level in one.py
one.py is being run directly

Si vous exécutez à la two.pyplace:

python two.py

Vous obtenez

top-level in one.py
one.py is being imported into another module
top-level in two.py
func() in one.py
two.py is being run directly

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


Réponse impressionnante, c'était la réponse la plus claire à mon avis. +1!
TheTechRobo36414519

+1 pour cette façon de voir les choses: la première ligne en retrait n'est exécutée qu'au début, jusqu'à ce que vous exécutiez des fonctions sur cette première ligne
Elijah Mock

719

L'explication la plus simple de la __name__variable (imho) est la suivante:

Créez les fichiers suivants.

# a.py
import b

et

# b.py
print "Hello World from %s!" % __name__

if __name__ == '__main__':
    print "Hello World again from %s!" % __name__

En les exécutant, vous obtiendrez cette sortie:

$ python a.py
Hello World from b!

Comme vous pouvez le voir, lorsqu'un module est importé, Python définit globals()['__name__']dans ce module le nom du module. De plus, lors de l'importation, tout le code du module est en cours d'exécution. Comme l' ifinstruction est évaluée, Falsecette partie n'est pas exécutée.

$ python b.py
Hello World from __main__!
Hello World again from __main__!

Comme vous pouvez le voir, lorsqu'un fichier est exécuté, Python définit globals()['__name__']ce fichier sur "__main__". Cette fois, l' ifinstruction est évaluée Trueet est en cours d'exécution.


513

Que fait le if __name__ == "__main__":?

Pour décrire 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 ifbloc ne s'exécutera que si le module est le point d'entrée de votre programme.

  • Il permet au code du module d'être importable par d'autres modules, sans exécuter le bloc de code ci-dessous lors de l'importation.


Pourquoi avons nous besoin de ça?

Développer et tester votre code

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

def do_important():
    """This function does something very important"""

Vous pouvez tester le module en ajoutant cet appel de la fonction en bas:

do_important()

et l'exécuter (sur une invite de commande) avec quelque chose comme:

~$ python important.py

Le problème

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

import important

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

# do_important() # I must remember to uncomment to execute this!

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

Une meilleure façon

La __name__variable pointe vers l'espace de noms où se trouve actuellement l'interpréteur Python.

À 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 Python interactive, c'est-à-dire la lecture, l'évaluation, la boucle d'impression ou la REPL de l'interpréteur), vous exécutez tout à partir de 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écuterez comme module principal (ou l'appellerez intentionnellement à partir d'un autre script).

Une façon encore meilleure

Il existe cependant un moyen Pythonique d'améliorer cela.

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

Si nous mettons le code que nous voulons exercer pendant que nous développons et testons une fonction comme celle-ci, puis vérifions '__main__'immédiatement après:

def main():
    """business logic for when running this module as the primary one!"""
    setup()
    foo = do_important()
    bar = do_even_more_important(foo)
    for baz in bar:
        do_super_important(baz)
    teardown()

# Here's our payoff idiom!
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 comme module principal.

Il permettra au module et à ses fonctions et classes d'être importés dans d'autres scripts sans exécuter la mainfonction, et permettra également au module (et à ses fonctions et classes) d'être appelé lors de l'exécution à partir d'un '__main__'module différent , c'est-à-dire

import important
important.main()

Cet idiome peut également être trouvé dans la documentation Python dans une explication du __main__module. Ce texte dit:

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

if __name__ == '__main__':
    main()

125

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


2
Pourquoi un fichier helloworld.pyavec juste print("hello world")dedans peut-il s'exécuter avec une commande python helloworld.pymême quand il n'y en a pas if __name__ == "__main__"?
hi15

83

Que fait if __name__ == "__main__":-il?

__name__est une variable globale (en Python, global signifie en fait au niveau du module ) qui existe dans tous les espaces de noms. Il s'agit généralement du nom du module (en tant que strtype).

Cependant, comme seul cas spécial, quel que soit le processus Python que vous exécutez, comme dans mycode.py:

python mycode.py

l'espace de noms global autrement anonyme est attribué la valeur de '__main__'son __name__.

Ainsi, y compris les dernières lignes

if __name__ == '__main__':
    main()
  • à la fin de votre script mycode.py,
  • lorsqu'il s'agit du module principal d'entrée qui est exécuté par un processus Python,

entraînera l' mainexécution de la fonction définie de manière unique de votre script .

Un autre avantage de l'utilisation de cette construction: vous pouvez également importer votre code en tant que module dans un autre script, puis exécuter la fonction principale si et quand votre programme décide:

import mycode
# ... any amount of other code
mycode.main()

72

Il y a beaucoup de prises différentes ici sur la mécanique du code en question, le "Comment", mais pour moi rien de tout cela n'avait de sens jusqu'à ce que je comprenne le "Pourquoi". Cela devrait être particulièrement utile pour les nouveaux programmeurs.

Prenez le fichier "ab.py":

def a():
    print('A function in ab file');
a()

Et un deuxième fichier "xy.py":

import ab
def main():
    print('main function: this is where the action is')
def x():
    print ('peripheral task: might be useful in other projects')
x()
if __name__ == "__main__":
    main()

Que fait réellement ce code?

Lorsque vous exécutez xy.py, vous import ab. L'instruction import exécute le module immédiatement à l'importation, donc ables opérations sont exécutées avant le reste de xy. Une fois terminé ab, il continue avecxy .

L'interpréteur garde une trace des scripts exécutés __name__. Lorsque vous exécutez un script - quel que soit le nom que vous lui avez donné - l'interpréteur l'appelle "__main__", ce qui en fait le script maître ou 'home' auquel on revient après avoir exécuté un script externe.

Tout autre script appelé à partir de ce "__main__"script se voit attribuer son nom de fichier comme __name__(par exemple, __name__ == "ab.py"). Par conséquent, la ligne if __name__ == "__main__":est le test de l'interpréteur pour déterminer s'il interprète / analyse le script «home» qui a été initialement exécuté, ou s'il jette temporairement un coup d'œil dans un autre script (externe). Cela donne au programmeur la flexibilité nécessaire pour que le script se comporte différemment s'il est exécuté directement par rapport à un appel externe.

Parcourons le code ci-dessus pour comprendre ce qui se passe, en nous concentrant d'abord sur les lignes non indentées et l'ordre dans lequel elles apparaissent dans les scripts. Souvenez-vous que les defblocs de fonction - ou - ne font rien par eux-mêmes jusqu'à ce qu'ils soient appelés. Ce que l'interprète pourrait dire s'il marmonnait:

  • Ouvrez xy.py en tant que fichier «home»; appelez-le "__main__"dans la __name__variable.
  • Importez et ouvrez un fichier avec __name__ == "ab.py".
  • Oh, une fonction. Je m'en souviendrai.
  • Ok, fonction a(); Je viens de l'apprendre. Impression d' une fonction dans un fichier ab .
  • Fin de fichier; retour à "__main__"!
  • Oh, une fonction. Je m'en souviendrai.
  • Un autre.
  • Fonction x(); ok, l'impression ' tâche périphérique: pourrait être utile dans d'autres projets '.
  • Qu'est-ce que c'est ça? Une ifdéclaration. Eh bien, la condition a été remplie (la variable __name__a été définie sur "__main__"), je vais donc entrer la main()fonction et imprimer « fonction principale: c'est là que se situe l'action ».

Les deux dernières lignes signifient: "S'il s'agit du "__main__"script ou" home ", exécutez la fonction appelée main()". C'est pourquoi vous verrez un def main():bloc en haut, qui contient le flux principal des fonctionnalités du script.

Pourquoi implémenter cela?

Rappelez-vous ce que j'ai dit plus tôt à propos des déclarations d'importation? Lorsque vous importez un module, il ne se contente pas de le «reconnaître» et d'attendre d'autres instructions - il exécute en fait toutes les opérations exécutables contenues dans le script. Ainsi, mettre la viande de votre script dans la main()fonction le met effectivement en quarantaine, le mettant en isolation afin qu'il ne s'exécute pas immédiatement lorsqu'il est importé par un autre script.

Encore une fois, il y aura des exceptions, mais la pratique courante est que les main()appels externes ne sont généralement pas appelés. Donc, vous vous demandez peut-être encore une chose: si nous n'appelons pas main(), pourquoi appelons-nous le script? C'est parce que de nombreuses personnes structurent leurs scripts avec des fonctions autonomes conçues pour être exécutées indépendamment du reste du code du fichier. Ils sont ensuite appelés plus tard ailleurs dans le corps du script. Ce qui m'amène à ceci:

Mais le code fonctionne sans lui

Oui c'est vrai. Ces fonctions distinctes peuvent être appelées à partir d'un script en ligne qui n'est pas contenu dans une main()fonction. Si vous êtes habitué (comme moi, dans mes premières étapes d'apprentissage de la programmation) à créer des scripts en ligne qui font exactement ce dont vous avez besoin, et vous essaierez de le comprendre à nouveau si vous avez besoin de cette opération à nouveau .. Eh bien, vous n'êtes pas habitué à ce type de structure interne à votre code, car il est plus compliqué à construire et ce n'est pas aussi intuitif à lire.

Mais c'est un script qui ne peut probablement pas avoir ses fonctions appelées en externe, car s'il le faisait, il commencerait immédiatement à calculer et à affecter des variables. Et il y a de fortes chances que si vous essayez de réutiliser une fonction, votre nouveau script est suffisamment lié à l'ancien pour qu'il y ait des variables en conflit.

En divisant des fonctions indépendantes, vous gagnez la possibilité de réutiliser votre travail précédent en les appelant dans un autre script. Par exemple, "example.py" peut importer "xy.py" et appeler x(), en utilisant la fonction 'x' de "xy.py". (Peut-être que cela met en majuscule le troisième mot d'une chaîne de texte donnée; créer un tableau NumPy à partir d'une liste de nombres et les mettre au carré; ou détendre une surface 3D. Les possibilités sont illimitées.)

(En passant , cette question contient une réponse de @kindall qui m'a finalement aidé à comprendre - le pourquoi, pas le comment. Malheureusement, il a été marqué comme un double de celui-ci , ce qui, je pense, est une erreur.)


52

Lorsqu'il y a certaines instructions dans notre module ( M.py) que nous voulons exécuter quand il s'exécutera en tant que principal (non importé), nous pouvons placer ces instructions (cas de test, instructions d'impression) sous ce ifbloc.

Comme par défaut (lorsque le module fonctionne en tant que principal, non importé), la __name__variable est définie sur "__main__", et lorsqu'elle sera importée, la __name__variable obtiendra une valeur différente, probablement le nom du module ( 'M'). Cela est utile pour exécuter différentes variantes d'un module ensemble, séparer leurs instructions d'entrée et de sortie spécifiques et également s'il existe des cas de test.

En bref , utilisez ce if __name__ == "main"bloc ' ' pour empêcher l'exécution de (certain) code lors de l'importation du module.


43

En termes simples, __name__une variable définie pour chaque script définit si le script est exécuté en tant que module principal ou s’exécute en tant que module importé.

Donc, si nous avons deux scripts;

#script1.py
print "Script 1's name: {}".format(__name__)

et

#script2.py
import script1
print "Script 2's name: {}".format(__name__)

La sortie de l'exécution de script1 est

Script 1's name: __main__

Et la sortie de l'exécution de script2 est:

Script1's name is script1
Script 2's name: __main__

Comme vous pouvez le voir, __name__nous indique quel code est le module «principal». C'est génial, car vous pouvez simplement écrire du code et ne pas avoir à vous soucier de problèmes structurels comme en C / C ++, où, si un fichier n'implémente pas de fonction `` principale '', il ne peut pas être compilé en tant qu'exécutable et s'il le fait, il ne peut alors pas être utilisé comme bibliothèque.

Supposons que vous écriviez un script Python qui fait quelque chose de génial et que vous implémentiez un ensemble de fonctions utiles à d'autres fins. Si je veux les utiliser, je peux simplement importer votre script et les utiliser sans exécuter votre programme (étant donné que votre code ne s'exécute que dans le if __name__ == "__main__":contexte). Alors qu'en C / C ++, vous devez diviser ces éléments en un module distinct qui inclut ensuite le fichier. Imaginez la situation ci-dessous;

Importation compliquée en C

Les flèches sont des liens d'importation. Pour trois modules essayant chacun d'inclure le code des modules précédents, il y a six fichiers (neuf, en comptant les fichiers d'implémentation) et cinq liens. Cela rend difficile l'inclusion d'un autre code dans un projet C à moins qu'il ne soit compilé spécifiquement en tant que bibliothèque. Maintenant imaginez-le pour Python:

Importation élégante en Python

Vous écrivez un module, et si quelqu'un veut utiliser votre code, il suffit de l'importer et la __name__variable peut aider à séparer la partie exécutable du programme de la partie bibliothèque.


2
L'illustration C / C ++ est incorrecte: 3 fois le même nom d'unité ( fichier1 ).
Wolf

40

Regardons la réponse d'une manière plus abstraite:

Supposons que nous ayons ce code dans x.py:

...
<Block A>
if __name__ == '__main__':
    <Block B>
...

Les blocs A et B sont exécutés lorsque nous exécutons x.py.

Mais juste le bloc A (et non B) est exécuté lorsque nous exécutons un autre module, y.pypar exemple, dans lequel x.pyest importé et le code est exécuté à partir de là (comme lorsqu'une fonction dans x.pyest appelée à partir de y.py).


1
Je n'ai pas pu modifier le message (minimum 6 caractères si un changement est requis). La ligne 14 a «xy» plutôt que «x.py».
alwaysLearning

35

Lorsque vous exécutez Python de manière interactive, la __name__variable locale se voit attribuer une valeur de __main__. De même, lorsque vous exécutez un module Python à partir de la ligne de commande, plutôt que de l'importer dans un autre module, son __name__attribut se voit attribuer une valeur de __main__, plutôt que le nom réel du module. De cette façon, les modules peuvent examiner leur propre __name__valeur pour déterminer par eux-mêmes comment ils sont utilisés, que ce soit comme support pour un autre programme ou comme application principale exécutée à partir de la ligne de commande. Ainsi, l'idiome suivant est assez courant dans les modules Python:

if __name__ == '__main__':
    # Do something appropriate here, like calling a
    # main() function defined elsewhere in this module.
    main()
else:
    # Do nothing. This module has been imported by another
    # module that wants to make use of the functions,
    # classes and other useful bits it has defined.

34

Considérer:

if __name__ == "__main__":
    main()

Il vérifie si l' __name__attribut du script Python l'est "__main__". En d'autres termes, si le programme lui-même est exécuté, l'attribut le sera __main__, donc le programme sera exécuté (dans ce cas, la main()fonction).

Cependant, si votre script Python est utilisé par un module, tout code en dehors de l' ifinstruction sera exécuté, il if \__name__ == "\__main__"est donc utilisé juste pour vérifier si le programme est utilisé comme module ou non, et décide donc s'il faut exécuter le code.


il semble qu'il ait été trop long pour écrire la réponse lumineuse +1
snr

27

Avant d'expliquer quoi que ce soit à ce sujet, if __name__ == '__main__'il est important de comprendre ce qui __name__est et ce qu'il fait.

Qu'est-ce que c'est __name__?

__name__est un DunderAlias - peut être considéré comme une variable globale (accessible à partir des modules) et fonctionne de manière similaire à global.

C'est une chaîne (globale comme mentionné ci-dessus) comme indiqué par type(__name__)(cédant <class 'str'>), et est une norme intégrée pour les versions Python 3 et Python 2 .

Où:

Il peut non seulement être utilisé dans les scripts, mais aussi dans l'interpréteur et les modules / packages.

Interprète:

>>> print(__name__)
__main__
>>>

Scénario:

test_file.py :

print(__name__)

Résultant en __main__

Module ou package:

somefile.py:

def somefunction():
    print(__name__)

test_file.py:

import somefile
somefile.somefunction()

Résultant en somefile

Notez que lorsqu'il est utilisé dans un package ou un module, __name__prend le nom du fichier. Le chemin d'accès du module ou du package n'est pas indiqué, mais possède son propre DunderAlias __file__, ce qui permet cela.

Vous devriez voir que, où __name__, où il est, le fichier principal (ou programme) retournera toujours__main__ , et s'il s'agit d'un module / package, ou de tout ce qui s'exécute sur un autre script Python, retournera le nom du fichier où il est originaire de.

Entraine toi:

Être une variable signifie que sa valeur peut être écrasée ("peut" ne signifie pas "devrait"), écraser la valeur de __name__entraînera un manque de lisibilité. Alors ne le faites pas, pour quelque raison que ce soit. Si vous avez besoin d'une variable, définissez une nouvelle variable.

Il est toujours supposé que la valeur de __name__soit __main__ou le nom du fichier. Une fois de plus, la modification de cette valeur par défaut provoquera plus de confusion que cela fera du bien, causant des problèmes plus loin.

exemple:

>>> __name__ = 'Horrify' # Change default from __main__
>>> if __name__ == 'Horrify': print(__name__)
...
>>> else: print('Not Horrify')
...
Horrify
>>>

Il est généralement considéré comme une bonne pratique d'inclure les if __name__ == '__main__'scripts dans.

Maintenant pour répondre if __name__ == '__main__':

Nous savons maintenant que le comportement des __name__choses devient plus clair:

An ifest une instruction de contrôle de flux qui contient le bloc de code qui s'exécutera si la valeur donnée est vraie. Nous avons vu que cela __name__peut prendre soit __main__le nom de fichier à partir duquel il a été importé.

Cela signifie que si __name__est égal à, __main__le fichier doit être le fichier principal et doit être en cours d'exécution (ou c'est l'interpréteur), et non un module ou un package importé dans le script.

Si en effet __name__prend la valeur de __main__alors tout ce qui se trouve dans ce bloc de code s'exécutera.

Cela nous indique que si le fichier en cours d'exécution est le fichier principal (ou si vous exécutez directement depuis l'interpréteur), cette condition doit s'exécuter. S'il s'agit d'un package, il ne devrait pas l'être et la valeur ne le sera pas __main__.

Modules:

__name__ peut également être utilisé dans les modules pour définir le nom d'un module

Variantes:

Il est également possible de faire d'autres choses moins courantes mais utiles avec __name__, certaines que je montrerai ici:

Exécution uniquement si le fichier est un module ou un package:

if __name__ != '__main__':
    # Do some useful things 

Exécuter une condition si le fichier est le principal et une autre s'il ne l'est pas:

if __name__ == '__main__':
    # Execute something
else:
    # Do some useful things

Vous pouvez également l'utiliser pour fournir des fonctions / utilitaires d'aide exécutables sur les packages et les modules sans l'utilisation complexe de bibliothèques.

Il permet également d'exécuter des modules à partir de la ligne de commande en tant que scripts principaux, ce qui peut également être très utile.


25

Je pense qu'il est préférable de casser la réponse en profondeur et en termes simples:

__name__: Chaque module en Python a un attribut spécial appelé __name__. Il s'agit d'une variable intégrée qui renvoie le nom du module.

__main__: Comme d'autres langages de programmation, Python a également un point d'entrée d'exécution, c'est-à-dire principal. '__main__' est le nom de la portée dans laquelle le code de niveau supérieur s'exécute . Fondamentalement, vous avez deux façons d'utiliser un module Python: l'exécuter directement en tant que script ou l'importer. Lorsqu'un module est exécuté en tant que script, il __name__est défini sur __main__.

Ainsi, la valeur de l' __name__attribut est définie sur __main__lorsque le module est exécuté en tant que programme principal. Sinon, la valeur de __name__ est définie pour contenir le nom du module.


23

C'est une option spéciale lorsqu'un fichier Python est appelé à partir de la ligne de commande. Ceci est généralement utilisé pour appeler une fonction "main ()" ou exécuter un autre code de démarrage approprié, comme la gestion des arguments de ligne de commande par exemple.

Il pourrait être écrit de plusieurs manières. Un autre est:

def some_function_for_instance_main():
    dosomething()


__name__ == '__main__' and some_function_for_instance_main()

Je ne dis pas que vous devriez utiliser ceci dans le code de production, mais cela sert à illustrer qu'il n'y a rien de "magique" if __name__ == '__main__'. C'est une bonne convention pour invoquer une fonction principale dans des fichiers Python.


7
Je considérerais cette mauvaise forme car vous 1) comptez sur les effets secondaires et 2) abusez and. andest utilisé pour vérifier si deux déclarations booléennes sont toutes les deux vraies. Puisque vous n'êtes pas intéressé par le résultat de la and, une ifdéclaration communique plus clairement vos intentions.
jpmc26

8
Laissant de côté la question de savoir si l'exploitation du comportement en court-circuit des opérateurs booléens comme mécanisme de contrôle de flux est un mauvais style ou non, le plus gros problème est que cela ne répond pas du tout à la question .
Mark Amery

@MarkAmery haha, sheesh, maintenant c'est le cas. 😊
contrat du professeur Falken a été

19

Il existe un certain nombre de variables que le système (interpréteur Python) fournit pour les fichiers source (modules). Vous pouvez obtenir leurs valeurs à tout moment, alors concentrons-nous sur la variable / l'attribut __name__ :

Lorsque Python charge un fichier de code source, il exécute tout le code qui s'y trouve. (Notez qu'il n'appelle pas toutes les méthodes et fonctions définies dans le fichier, mais il les définit.)

Avant que l'interpréteur n'exécute le fichier de code source, il définit quelques variables spéciales pour ce fichier; __name__ est l'une de ces variables spéciales que Python définit automatiquement pour chaque fichier de code source.

Si Python charge ce fichier de code source en tant que programme principal (c'est-à-dire le fichier que vous exécutez), il définit la variable spéciale __name__ pour que ce fichier ait une valeur "__main__" .

Si cela est importé d'un autre module, __name__ sera défini sur le nom de ce module.

Donc, dans votre exemple en partie:

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))

signifie que le bloc de code:

lock = thread.allocate_lock()
thread.start_new_thread(myfunction, ("Thread #: 1", 2, lock))
thread.start_new_thread(myfunction, ("Thread #: 2", 2, lock))

ne sera exécuté que lorsque vous exécuterez directement le module; le bloc de code ne s'exécutera pas si un autre module l'appelle / l'importe car la valeur de __name__ ne sera pas égale à " main " dans cette instance particulière.

J'espère que cela vous aidera.


17

if __name__ == "__main__": est fondamentalement l'environnement de script de niveau supérieur, et il spécifie l'interpréteur qui («J'ai la priorité la plus élevée à exécuter en premier»).

'__main__'est le nom de la portée dans laquelle le code de niveau supérieur s'exécute. Un module __name__est défini égal à '__main__'lorsqu'il est lu à partir d'une entrée standard, d'un script ou d'une invite interactive.

if __name__ == "__main__":
    # Execute only if run as a script
    main()

17

J'ai tellement lu tout au long des réponses sur cette page. Je dirais que si vous connaissez la chose, vous comprendrez certainement ces réponses, sinon, vous êtes toujours confus.

Pour être bref, vous devez connaître plusieurs points:

  1. import a l'action exécute en fait tout ce qui peut être exécuté dans "a"

  2. En raison du point 1, il se peut que vous ne souhaitiez pas que tout soit exécuté dans "a" lors de son importation

  3. Pour résoudre le problème du point 2, python vous permet de mettre une vérification de condition

  4. __name__est une variable implicite dans tous les .pymodules; quand a.pyest importé, la valeur __name__du a.pymodule est fixé à son nom de fichier " a« ; quand a.pyest exécuté directement en utilisant " python a.py", ce qui signifie a.pyest le point d'entrée, alors la valeur __name__de a.pymodule est définie sur une chaîne__main__

  5. En fonction du mécanisme utilisé par python pour définir la variable __name__de chaque module, savez-vous comment atteindre le point 3? La réponse est assez simple, non? Mettez un si la condition: if __name__ == "__main__": ...; vous pouvez même mettre si __name__ == "a"selon votre besoin fonctionnel

La chose importante que python est spécial au point 4! Le reste n'est qu'une logique de base.


1
Oui, le point 1 est essentiel à comprendre. De là, la nécessité de ce mécanisme devient claire.
Eureka

16

Considérer:

print __name__

La sortie pour ce qui précède est __main__.

if __name__ == "__main__":
  print "direct method"

L'instruction ci-dessus est vraie et affiche la "méthode directe" . Supposons que s'ils ont importé cette classe dans une autre classe, elle n'imprime pas la "méthode directe" car, lors de l'importation, elle sera définie __name__ equal to "first model name".


14

Vous pouvez rendre le fichier utilisable en tant que script ainsi qu'en tant que module importable .

fibo.py (un module nommé fibo)

# Other modules can IMPORT this MODULE to use the function fib
def fib(n):    # write Fibonacci series up to n
    a, b = 0, 1
    while b < n:
        print(b, end=' ')
        a, b = b, a+b
    print()

# This allows the file to be used as a SCRIPT
if __name__ == "__main__":
    import sys
    fib(int(sys.argv[1]))

Référence: https://docs.python.org/3.5/tutorial/modules.html


14

La raison pour

if __name__ == "__main__":
    main()

est principalement pour éviter les problèmes de verrouillage d'importation qui résulteraient de l' importation directe de code . Vous souhaitez main()exécuter si votre fichier a été directement invoqué (c'est le __name__ == "__main__"cas), mais si votre code a été importé, l'importateur doit entrer votre code à partir du vrai module principal pour éviter les problèmes de verrouillage d'importation.

Un effet secondaire est que vous vous connectez automatiquement à une méthodologie qui prend en charge plusieurs points d'entrée. Vous pouvez exécuter votre programme en utilisant main()comme point d'entrée, mais ce n'est pas obligatoire . Bien que setup.pyprévu main(), d'autres outils utilisent des points d'entrée alternatifs. Par exemple, pour exécuter votre fichier en tant que gunicornprocessus, vous définissez une app()fonction au lieu d'un main(). Tout comme avec setup.py, gunicornimporte votre code afin que vous ne vouliez pas qu'il fasse quoi que ce soit pendant son importation (en raison du problème de verrouillage d'importation).


3
Bon pour en savoir plus sur le verrouillage d'importation . Pourriez-vous s'il vous plaît expliquer la connexion à une méthodologie qui [...] se sépare un peu plus?
Wolf

1
@Wolf: Bien sûr. J'ai ajouté quelques phrases sur la méthodologie des points d'entrée multiples.
personal_cloud

11

Cette réponse s'adresse aux programmeurs Java qui apprennent Python. Chaque fichier Java contient généralement une classe publique. Vous pouvez utiliser cette classe de deux manières:

  1. Appelez la classe à partir d'autres fichiers. Il vous suffit de l'importer dans le programme appelant.

  2. Exécutez la classe de façon autonome, à des fins de test.

Dans ce dernier cas, la classe doit contenir une méthode publique statique void main (). En Python, cet objectif est atteint par l'étiquette définie globalement '__main__'.


11

Le code sous if __name__ == '__main__': ne sera exécuté que si le module est appelé en tant que script .

À titre d'exemple, considérons le module suivant my_test_module.py:

# my_test_module.py

print('This is going to be printed out, no matter what')

if __name__ == '__main__':
    print('This is going to be printed out, only if user invokes the module as a script')

1ère possibilité: importer my_test_module.pydans un autre module

# main.py

import my_test_module

if __name__ == '__main__':
    print('Hello from main.py')

Maintenant, si vous invoquez main.py:

python main.py 

>> 'This is going to be printed out, no matter what'
>> 'Hello from main.py'

Notez que seule l' print()instruction de niveau supérieur dans my_test_moduleest exécutée.


2ème possibilité: invoquer my_test_module.pycomme script

Maintenant, si vous exécutez en my_test_module.pytant que script Python, les deux print()instructions seront exécutées:

python my_test_module.py

>>> 'This is going to be printed out, no matter what'
>>> 'This is going to be printed out, only if user invokes the module as a script'

10

Chaque module en python a un attribut appelé __name__. La valeur de l' __name__ attribut est __main__ lorsque le module est exécuté directement, comme python my_module.py. Sinon (comme quand vous dites import my_module) la valeur de __name__ est le nom du module.

Petit exemple à expliquer en bref.

#Script test.py

apple = 42

def hello_world():
    print("I am inside hello_world")

if __name__ == "__main__":
    print("Value of __name__ is: ", __name__)
    print("Going to call hello_world")
    hello_world()

Nous pouvons l'exécuter directement

python test.py  

Production

Value of __name__ is: __main__
Going to call hello_world
I am inside hello_world

Supposons maintenant que nous appelons le script ci-dessus à partir d'un autre script

#script external_calling.py

import test
print(test.apple)
test.hello_world()

print(test.__name__)

Lorsque vous exécutez cela

python external_calling.py

Production

42
I am inside hello_world
test

Donc, ci-dessus est explicite que lorsque vous appelez test à partir d'un autre script, if loop __name__in test.pyne s'exécutera pas.


6

Si ce fichier .py est importé par d'autres fichiers .py, le code sous "l'instruction if" ne sera pas exécuté.

Si ce .py est exécuté par python this_py.pysous shell, ou double-cliqué dans Windows. le code sous "l'instruction if" sera exécuté.

Il est généralement écrit pour les tests.


6

Si l'interpréteur python exécute un module particulier, __name__la variable globale aura une valeur"__main__"

  def a():
      print("a")
  def b():
      print("b")

  if __name__ == "__main__": 

          print ("you can see me" )
          a()
  else: 

          print ("You can't see me")
          b()

Lorsque vous exécutez ce script imprime, vous pouvez me voir

une

Si vous importez ce fichier, dites A au fichier B et exécutez le fichier B, puis if __name__ == "__main__"dans le fichier A devient faux, donc il s'imprime Vous ne pouvez pas me voir

b


5

Toutes les réponses ont à peu près expliqué la fonctionnalité. Mais je vais donner un exemple de son utilisation qui pourrait aider à clarifier davantage le concept.

Supposons que vous ayez deux fichiers Python, a.py et b.py. Maintenant, a.py importe b.py. Nous exécutons le fichier a.py, où le code "import b.py" est exécuté en premier. Avant l'exécution du reste du code a.py, le code du fichier b.py doit s'exécuter complètement.

Dans le code b.py, il y a du code exclusif à ce fichier b.py et nous ne voulons pas qu'un autre fichier (autre que le fichier b.py), qui a importé le fichier b.py, l'exécute.

Voilà donc ce que cette ligne de code vérifie. S'il s'agit du fichier principal (c'est-à-dire b.py) exécutant le code, ce qui n'est pas le cas dans ce cas (a.py est le fichier principal en cours d'exécution), seul le code est exécuté.


4

Créez un fichier, a.py :

print(__name__) # It will print out __main__

__name__est toujours égal à __main__chaque fois que ce fichier est exécuté, ce qui montre qu'il s'agit du fichier principal.

Créez un autre fichier, b.py , dans le même répertoire:

import a  # Prints a

Exécuter. Il affichera un , c'est-à-dire le nom du fichier importé .

Donc, pour montrer deux comportements différents du même fichier , c'est une astuce couramment utilisée:

# Code to be run when imported into another python file

if __name__ == '__main__':
    # Code to be run only when run directly

4

si nom == ' principal ':

Nous voyons si __name__ == '__main__':souvent.

Il vérifie si un module est importé ou non.

En d'autres termes, le code dans le ifbloc ne sera exécuté que lorsque le code s'exécute directement. Ici directlysignifie not imported.

Voyons ce qu'il fait en utilisant un code simple qui affiche le nom du module:

# test.py
def test():
   print('test module name=%s' %(__name__))

if __name__ == '__main__':
   print('call test()')
   test()

Si nous exécutons le code directement via python test.py, le nom du module est __main__:

call test()
test module name=__main__

4

C'est simplement le point d'entrée pour exécuter le fichier, comme la mainfonction dans le langage de programmation C.


8
Cette réponse fait l'hypothèse que l'OP (ou tout utilisateur ayant une question similaire) est à la fois familier avec C et sait ce qu'est un point d'entrée.
arredond

1
Cette réponse suppose également qu'aucun code (autre que les définitions sans effets secondaires) n'a lieu avant le if __name__ == "__main__"bloc. Techniquement, le haut du script exécuté est le point d'entrée du programme.
Charlie Harding le
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.