Question Que fait si __name__ == "__main__": faire?


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

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

4128
2018-01-07 04:11


origine


Réponses:


Lorsque l'interpréteur Python lit un fichier source, il exécute tout le code qui s'y trouve.

Avant d'exécuter le code, il va définir quelques variables spéciales. Par exemple, si l'interpréteur Python exécute ce module (le fichier source) en tant que programme principal, il définit le __name__ variable pour avoir une valeur "__main__". Si ce fichier est importé d'un autre module, __name__ sera défini sur le nom du module.

Dans le cas de votre script, supposons qu'il s'exécute en tant que fonction principale, par ex. vous avez dit quelque chose comme

python threading_example.py

sur la ligne de commande. Après avoir configuré les variables spéciales, il exécutera le import déclaration et charger ces modules. Il évaluera ensuite def bloquer, créer un objet fonction et créer une variable appelée myfunction qui pointe vers l'objet fonction. Il lira ensuite le if déclaration et voir que __name__ est égal "__main__", donc il va exécuter le bloc montré là.

Une raison à cela est que parfois vous écrivez un module (un .py fichier) où il peut être exécuté directement. Alternativement, il peut également être importé et utilisé dans un autre module. En faisant la vérification principale, vous pouvez avoir ce code seulement exécuté quand vous voulez exécuter le module en tant que programme et ne pas l'exécuter quand quelqu'un veut juste importer votre module et appeler vos fonctions eux-mêmes.

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


4407
2018-01-07 04:26



Lorsque votre script est exécuté en le passant en tant que commande à l'interpréteur Python,

python myscript.py

tout le code qui se trouve au niveau d'indentation 0 est exécuté. Les fonctions et les classes définies sont bien définies, mais aucun de leur code n'est exécuté. Contrairement à d'autres langues, il n'y a pas main() fonction qui s'exécute automatiquement - le main() La fonction est implicitement tout le code au plus haut niveau.

Dans ce cas, le code de niveau supérieur est un if bloc. __name__ est une variable intégrée qui évalue le nom du module courant. Cependant, si un module est exécuté directement (comme dans myscript.py ci-dessus), puis __name__ à la place est mis à 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 if clause ci-dessus ne sera pas exécuté car la condition n'est pas remplie. À titre d'exemple, considérons 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 appelez l'interpréteur comme

python one.py

La sortie sera

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

Si vous courez two.py au lieu:

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 one est chargé, son __name__ équivaut à "one" au lieu de "__main__".


1403
2018-01-07 04:28



L'explication la plus simple pour __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__

Les exécuter vous obtiendra cette sortie:

$ python a.py
Hello World from b!

Comme vous pouvez le constater, lorsqu'un module est importé, les jeux Python globals()['__name__'] dans ce module au nom du module.

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

Comme vous pouvez le voir, lorsqu'un fichier est exécuté, les jeux Python globals()['__name__'] dans ce fichier "__main__".


560
2018-01-07 11:35



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

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.

  • Donc, code sous le if Le bloc ne fonctionnera 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 sous import.


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

Toi pourrait 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 voulez importer le module dans un autre script:

import important

À l'importation, le do_important fonction serait appelée, donc vous auriez probablement commenter votre appel de fonction, do_important(), au fond.

# 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 signifie que vous risquez d'oublier, ce qui rend votre processus de développement plus difficile.

Une meilleure façon

le __name__ des points variables vers l'espace de noms où se trouve l'interpréteur Python pour l'instant.

Dans 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 Read, Eval, Print Loop 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 n'exécutera que lorsque vous l'exécutez en tant que module principal (ou l'appelez intentionnellement à partir d'un autre script).

Une façon encore meilleure

Cependant, il existe un moyen Pythonien de s'améliorer.

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 comme nous développons et testons dans une fonction comme celle-ci, puis faites notre contrôle pour '__main__' juste 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 fonctionnera si nous exécutons le module en tant que module principal.

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

import important
important.main()

Cet idiome peut également être trouvé dans la documentation Python dans une explication de la __main__ module. Ce texte dit:

Ce module représente le périmètre (autrement anonyme) dans lequel le   programme principal de l'interpréteur s'exécute - les commandes sont lues   entrée standard, à partir d'un fichier de script ou d'une invite interactive. Il   est cet environnement dans lequel la strophe "scénario conditionnel" idiomatique   provoque l'exécution d'un script:

if __name__ == '__main__':
    main()

412
2017-11-23 04:38



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


92
2018-01-07 04:14



Qu'est-ce que if __name__ == "__main__": faire?

__name__ est une variable globale (en Python, global signifie réellement sur le niveau du module) qui existe dans tous les espaces de noms. C'est typiquement le nom du module (en tant que str type).

Comme seul cas particulier, cependant, quel que soit le processus Python exécuté, comme dans mycode.py:

python mycode.py

l'espace de noms global anonyme est assigné la valeur de '__main__' à son __name__.

Ainsi, y compris les dernières lignes

if __name__ == '__main__':
    main()
  • à la fin de votre script mycode.py,
  • quand c'est le module primaire, point d'entrée qui est exécuté par un processus Python,

provoquera la définition unique de votre script main fonction à exécuter.

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

57
2017-10-14 20:22



Il y a beaucoup de différentes prises ici sur la mécanique du code en question, le "Comment", mais pour moi rien de tout cela n'a de sens jusqu'à ce que j'ai compris 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 ce code?

Lorsque vous exécutez xy.py, toi import ab. L'instruction d'importation exécute le module immédiatement à l'importation. ables opérations sont exécutées avant le reste de xy's. Une fois terminé avec ab, ça continue avec xy.

L'interpréteur garde la trace des scripts qui s'exécutent avec __name__. Lorsque vous exécutez un script - peu importe ce que vous l'avez nommé - l'interpréteur l'appelle "__main__", ce qui en fait le maître ou le script 'home' qui est retourné après avoir exécuté un script externe.

Tout autre script appelé de cette "__main__" script est assigné son nom de fichier en tant que son __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é exécuté initialement, ou s'il est temporairement en train d'explorer un autre script (externe). Cela donne au programmeur une flexibilité pour que le script se comporte différemment s'il est exécuté directement par rapport à un appel externe.

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

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

Les deux lignes du bas signifient: "Si c'est le "__main__" ou script 'home', exécutez la fonction appelée main()"C'est pourquoi vous verrez un def main(): bloquer haut, qui contient le flux principal de la fonctionnalité 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 le «reconnaît» pas et attend des instructions supplémentaires: il exécute en fait toutes les opérations exécutables contenues dans le script. Donc, mettre la viande de votre script dans le main() La fonction le met en quarantaine, en le mettant de manière à ce qu'il ne soit pas exécuté immédiatement lorsqu'il est importé par un autre script.

Encore une fois, il y aura des exceptions, mais la pratique courante est que main() n'est généralement pas appelé en externe. Vous vous demandez peut-être encore une chose: si nous n'appelons pas main(), pourquoi appelons-nous le script? C'est parce que beaucoup de gens structurent leurs scripts avec des fonctions autonomes qui sont construites pour être exécutées indépendamment du reste du code dans le 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

Oui c'est vrai. Ces fonctions séparées pouvez être appelé à partir d'un script en ligne qui n'est pas contenu dans un main() fonction. Si vous êtes habitué (comme je le suis, dans mes premières étapes de programmation) à construire des scripts en ligne qui font exactement ce dont vous avez besoin, et vous essaierez de le comprendre à nouveau si jamais vous avez encore besoin de cette opération. eh bien, vous n'êtes pas habitué à ce type de structure interne à votre code, car c'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, parce que si c'était le cas, il commencerait immédiatement à calculer et assigner des variables. Et il y a des chances que si vous essayez de réutiliser une fonction, votre nouveau script soit assez proche de l'ancien pour qu'il y ait des variables en conflit.

En divisant les fonctions indépendantes, vous pouvez 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 c'est en capitalisant le troisième mot d'une chaîne de texte donnée, en créant un tableau NumPy à partir d'une liste de nombres et en les mettant au carré, ou en détruisant une surface 3D.

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


47
2017-09-29 04:33



Quand il y a certaines déclarations dans notre module (M.py) nous voulons être exécutés quand il sera exécuté en tant que main (non importé), nous pouvons placer ces déclarations (cas de test, déclarations d'impression) sous cette ifbloc.

Par défaut (lorsque le module est exécuté en tant que principal, non importé), le __name__ variable est définie sur "__main__"et quand il sera importé __name__ variable aura une valeur différente, très probablement le nom du module ('M'). Ceci est utile pour exécuter différentes variantes d'un module ensemble, et pour séparer leurs instructions d'entrée et de sortie spécifiques et aussi s'il y a des cas de test.

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


39
2018-04-03 14:09



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 seulement le bloc A (et non B) est exécuté lorsque nous exécutons un autre module, "y.py" par exemple, dans lequel xy est importé et le code est exécuté à partir de là (comme quand une fonction dans "x.py" est appelé depuis y.py).


32
2018-01-20 17:48