Que fait le if __== "__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 __== "__main__":
lock = thread.allocate_lock()
thread.start_new_thread(myfunction, ("Thread #: 1", 2, lock))
thread.start_new_thread(myfunction, ("Thread #: 2", 2, lock))
Chaque fois que l'interprète Python lit un fichier source, il effectue 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 vérifications __name__
que nous voyons toujours dans les scripts Python.
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 nommé 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 __guard")
if __== '__main__':
functionA()
functionB()
print("after __guard")
Lorsque l'interpète Python lit un fichier source, il définit d'abord quelques variables spéciales. Dans ce cas, nous nous soucions de 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 exemple,.
python foo.py
l'interprète affectera la chaîne codée en dur "__main__"
à la variable __name__
, c'est-à-dire.
# It's as if the interpreter inserts this at the top
# of your module when run as the main program.
__= "__main__"
Lorsque votre module est importé par un autre
D'autre part, supposons qu'un autre module soit le programme principal et qu'il importe votre module. Cela signifie qu'il existe une déclaration comme celle-ci dans le programme principal ou dans un autre module importé par le programme principal:
# Suppose this is in some other main program.
import foo
Dans ce cas, l'interpréteur examinera le nom de fichier de votre module, foo.py
, enlèvera le .py
et assignera cette chaîne à la variable __name__
de votre module, c'est-à-dire.
# It's as if the interpreter inserts this at the top
# of your module when it's imported from another module.
__= "foo"
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
Il imprime la chaîne "before import"
(sans guillemets).
Il charge le module math
et l'assigne à une variable appelée math
. Ceci équivaut à remplacer import math
par ce qui suit (notez que __import__
est une fonction de bas niveau dans 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")
Il imprime la chaîne "before functionA"
.
Il exécute le bloc def
en créant un objet fonction, puis en l'affectant à une variable appelée functionA
.
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'affectant à une variable appelée functionB
.
Il imprime la chaîne "before __guard"
.
niquement lorsque votre module est le programme principal
__name__
a bien été défini sur "__main__"
et appelle les deux fonctions en imprimant les chaînes "Function A"
et "Function B 10.0"
.niquement lorsque votre module est importé par un autre
__name__
sera "foo"
, pas "__main__"
, et il ignorer le corps de l'instruction if
.toujours
"after __guard"
sera imprimée dans les deux cas.Résumé
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 __guard
Function A
Function B 10.0
after __guard
# What gets printed if foo is imported as a regular module
before import
before functionA
before functionB
before __guard
after __guard
Vous pourriez naturellement vous demander pourquoi quelqu'un voudrait cela. Parfois, vous voulez écrire un fichier .py
qui peut être 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 dans lequel il exécute des tests unitaires ou une démonstration.
Votre module est uniquement utilisé en tant que programme principal, mais il comporte des tests unitaires. Le framework 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 simplement parce qu'il importe le module.
Votre module est principalement utilisé en tant que programme principal, mais il fournit également une API conviviale aux programmeurs pour les utilisateurs avancés.
Au-delà de ces exemples, il est élégant que l'exécution d'un script dans Python ne fasse que configurer quelques variables magiques et importer le script. "Exécuter" le script est un effet secondaire de l'importation du module du script.
Question: Puis-je avoir plusieurs __name__
blocs de contrôle? Réponse: c'est étrange de le faire, mais le langage ne vous arrêtera pas.
Supposons que ce qui suit se trouve dans foo2.py
. Que se passe-t-il si vous dites python foo2.py
sur 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 __== "__main__":
print("m1")
functionA()
print("m2")
print("t2")
__name__
check in 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")
# Suppose this is in foo4.py
__= "__main__"
def bar():
print("bar")
print("before __guard")
if __== "__main__":
bar()
print("after __guard")
Lorsque votre script est exécuté en le passant en tant que commande à l'interpréteur Python,
python myscript.py
tout le code 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 fonction main()
qui s'exécute automatiquement - la fonction main()
correspond implicitement à tout le code situé au niveau supérieur.
Dans ce cas, le code de niveau supérieur est un bloc if
. __name__
est une variable intégrée qui correspond au nom du module actuel. Toutefois, si un module est exécuté directement (comme dans myscript.py
ci-dessus), alors __name__
est défini à la place sur la chaîne "__main__"
. Ainsi, vous pouvez tester si votre script est exécuté directement ou importé par autre chose en testant
if __== "__main__":
...
Si votre script est importé dans un autre module, ses diverses définitions de fonctions et de classes seront importées et son code de niveau supérieur sera exécuté, mais le code contenu dans le corps alors de la clause if
ne sera pas obtenu. exécuter car la condition n'est pas remplie. Comme exemple de base, considérons les deux scripts suivants:
# file one.py
def func():
print("func() in one.py")
print("top-level in one.py")
if __== "__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 __== "__main__":
print("two.py is being run directly")
else:
print("two.py is being imported into another module")
Maintenant, si vous appelez l'interprète en tant que
python one.py
La sortie sera
top-level in one.py
one.py is being run directly
Si vous exécutez two.py
à la place:
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__
est égal à "one"
au lieu de "__main__"
.
L'explication la plus simple pour la variable __name__
(imho) est la suivante:
Créez les fichiers suivants.
# a.py
import b
et
# b.py
print "Hello World from %s!" % __name__
if __== '__main__':
print "Hello World again from %s!" % __name__
Les exécuter vous donnera cette sortie:
$ python a.py
Hello World from b!
Comme vous pouvez le constater, lorsqu'un module est importé, Python définit globals()['__name__']
dans ce module sur le nom du module. De plus, lors de l'importation, tout le code du module est en cours d'exécution. Comme l'instruction if
est évaluée à False
, cette partie n'est pas exécutée.
$ python b.py
Hello World from __main__!
Hello World again from __main__!
Comme vous pouvez le constater, lorsqu'un fichier est exécuté, Python définit globals()['__name__']
dans ce fichier sur "__main__"
. Cette fois, l'instruction if
est évaluée à True
et est en cours d'exécution.
Que fait le
if __== "__main__":
?
Pour décrire les bases:
La variable globale, __name__
, dans le module qui constitue le point d'entrée de votre programme, est '__main__'
. Sinon, c'est le nom par lequel vous importez le module.
Ainsi, le code situé sous le bloc if
ne fonctionnera 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 ci-dessous lors de l'importation.
Pourquoi avons nous besoin de ça?
Supposons que vous écriviez un script Python conçu pour être utilisé en tant que module:
def do_important():
"""This function does something very important"""
Vous pourriez tester le module en ajoutant cet appel de la fonction au bas:
do_important()
et l'exécuter (sur une invite de commande) avec quelque chose comme:
~$ python important.py
Toutefois, si vous souhaitez importer le module dans un autre script:
import important
Lors de l’importation, la fonction do_important
sera appelée. Vous devrez donc probablement commenter votre appel de fonction, do_important()
, en bas.
# do_important() # I must remember to uncomment to execute this!
Et ensuite, vous devrez vous rappeler si vous avez commenté votre appel de fonction de test. Et cette complexité supplémentaire signifierait que vous oublierez probablement, rendant votre processus de développement plus gênant.
La variable __name__
pointe vers l’espace de nommage où que se trouve l’interpréteur Python.
Dans un module importé, c'est le nom de ce module.
Mais dans le module principal (ou dans une session interactive Python, c'est-à-dire les fonctions 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 __== "__main__":
do_important()
Avec ce qui précède, votre code ne sera exécuté que lorsque vous l'exécuterez en tant que module principal (ou l'appellera intentionnellement à partir d'un autre script).
Cependant, il existe un moyen pythonique d'améliorer cette situation.
Que faire si nous voulons exécuter ce processus métier de l'extérieur du module?
Si nous mettons le code que nous voulons exercer pendant que nous développons et testons dans une fonction comme celle-ci, nous vérifions ensuite '__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 __== '__main__':
main()
Nous avons maintenant une dernière fonction pour la fin de notre module, qui sera exécutée si nous exécutons le module en tant que module principal.
Cela permettra au module, à ses fonctions et à ses classes d'être importés dans d'autres scripts sans exécuter la fonction main
, et permettra également au module (ainsi qu'à ses fonctions et ses classes) d'être appelé lors de l'exécution à partir d'un autre '__main__'
module, c'est-à-dire.
import important
important.main()
Cet idiome peut également être trouvé dans la documentation de Python dans une explication du module __main__
. Ce texte indique:
Ce module représente l’étendue (sinon anonyme) dans laquelle le programme principal de l’interprète s’exécute - commandes lues soit à partir d’une entrée standard, d’un fichier script, soit d’une invite interactive. C'est dans cet environnement que la strophe idiomatique de "script conditionnel" provoque l'exécution d'un script:
if __== '__main__': main()
if __== "__main__"
est la partie qui s'exécute lorsque le script est exécuté à partir de la ligne de commande (par exemple) à l'aide d'une commande telle que python myscript.py
.
Que fait _
if __== "__main__":
_?
___name__
_ est une variable globale (en Python, global signifie en réalité sur le niveau du module ) qui existe dans tous les espaces-noms. Il s'agit généralement du nom du module (sous la forme d'un type str
).
Cependant, comme seul cas particulier, dans le processus Python que vous exécutez, comme dans mycode.py:
_python mycode.py
_
la valeur de _'__main__'
_ est attribuée à l'espace de noms global autrement anonyme, à ___name__
_.
Ainsi, y compris les dernières lignes
_if __== '__main__':
main()
_
entraînera l'exécution de la fonction main
définie de manière unique dans 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()
_
Il y a beaucoup de points de vue différents sur la mécanique du code en question, le "comment", mais pour moi cela n'avait aucun sens tant que je n'avais pas 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 __== "__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 lors de l'importation. Les opérations de ab
sont donc exécutées avant le reste des xy
. Une fois terminé avec ab
, il continue avec xy
.
L'interprète enregistre les scripts en cours d'exécution avec __name__
. Quel que soit le nom que vous avez utilisé, l'interprète appelle "__main__"
le script que vous exécutez, ce qui en fait le script maître ou 'home' auquel le script externe est renvoyé.
Tout autre script appelé à partir de ce script "__main__"
se voit attribuer son nom de fichier sous le nom __name__
(par exemple, __== "ab.py"
). Par conséquent, la ligne if __== "__main__":
est le test de l'interprète permettant de déterminer s'il interprète/analyse le script "home" initialement exécuté ou s'il est temporairement inséré dans un autre script (externe). Cela donne au programmeur la possibilité de faire en sorte 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 commençant par les lignes non mises en retrait et leur ordre d'apparition dans les scripts. Rappelez-vous cette fonction - ou def
- les blocs ne font rien d’eux-mêmes tant qu’ils ne sont pas appelés. Ce que l'interprète pourrait dire s'il marmonnait tout seul:
"__main__"
dans la variable __name__
.__== "ab.py"
.a()
; Je viens d'apprendre ça. Impression ' Fonction dans le fichier ab '."__main__"
!x()
; ok, l'impression ' tâche périphérique: peut être utile dans d'autres projets '.if
. Eh bien, la condition est remplie (la variable __name__
a été définie sur "__main__"
), je vais donc entrer la fonction main()
et imprimer ' la fonction principale: c'est ici l'action est '.Les deux lignes du bas signifient: "S'il s'agit du script "__main__"
ou" home ", exécutez la fonction nommée main()
". C'est pourquoi vous verrez un bloc def main():
qui contient le flux principal des fonctionnalités du script.
Pourquoi implémenter ceci?
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 n'attend pas d'instructions supplémentaires: il exécute en fait toutes les opérations exécutables contenues dans le script. Ainsi, placer le contenu de votre script dans la fonction main()
le met effectivement en quarantaine, de manière à ce 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 main()
ne soit généralement pas appelé en externe. Donc, vous vous demandez peut-être une dernière chose: si nous n’appelons pas main()
, pourquoi appelons-nous le script? En effet, 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 dans le corps du script. Ce qui m'amène à ceci:
Mais le code fonctionne sans elle
Oui c'est vrai. Ces fonctions distinctes peuvent être appelées à partir d'un script en ligne non contenu dans une fonction main()
. Si vous êtes habitué (comme je le suis à mes débuts en programmation) à construire des scripts en ligne qui font exactement ce dont vous avez besoin, et vous essayerez de le comprendre 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 moins intuitif à lire.
Mais c'est un script dont les fonctions ne peuvent probablement pas être appelées à l'extérieur, 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 séparant des fonctions indépendantes, vous avez la possibilité de réutiliser vos travaux précédents en les appelant dans un autre script. Par exemple, "exemple.py" peut importer "xy.py" et appeler x()
, en utilisant la fonction "x" de "xy.py". (Peut-être met-il 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 empêcher une surface 3D de gêner. Les possibilités sont illimitées.)
(À part, 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 une copie de celui-ci =, ce que je pense est une erreur.)
Quand il y a certaines instructions dans notre module (M.py
) nous voulons être exécutées quand il sera exécuté en tant que main (non importé), nous pouvons placer ces instructions (tests-case, instructions print) sous cette if
block.
Comme par défaut (lorsque le module fonctionne en tant que principal, non importé), la variable __name__
est définie sur "__main__"
et, lorsqu’elle sera importée, la variable __name__
obtiendra une valeur différente. 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 également s'il existe des cas de test.
En bref, utilisez ce bloc 'if __== "main"
' 'pour empêcher le code (certain) d'être exécuté lors de l'importation du module.
En termes simples, __name__
est une variable définie pour chaque script. Elle définit si le script est exécuté en tant que module principal ou 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__)
Le résultat de l'exécution du script1 est
Script 1's name: __main__
Et le résultat de l'exécution de script2 est:
Script1's name is script1
Script 2's name: __main__
Comme vous pouvez le constater, __name__
nous indique quel code est le module "principal". C’est formidable, car vous pouvez simplement écrire du code sans avoir à vous soucier de problèmes structurels, comme en C/C++, où, si un fichier ne met pas en oeuvre une fonction "principale", il ne peut pas être compilé en tant qu’exécutable. il ne peut alors être utilisé comme une bibliothèque.
Supposons que vous écriviez un script Python qui fasse quelque chose de très bien 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 contexte if __== "__main__":
). Par contre, en C/C++, vous devrez répartir ces éléments dans un module séparé qui inclut ensuite le fichier. Imaginez la situation ci-dessous;
Les flèches sont des liens d'importation. Pour trois modules essayant chacun d'inclure le code de module précédent, il existe 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 spécifiquement compilé en tant que bibliothèque. Maintenant, imaginez-le pour Python:
Vous écrivez un module et si quelqu'un veut utiliser votre code, il l'importe et la variable __name__
peut aider à séparer la partie exécutable du programme de la partie bibliothèque.
Regardons la réponse d'une manière plus abstraite:
Supposons que nous ayons ce code dans x.py:
...
<Block A>
if __== '__main__':
<Block B>
...
Les blocs A et B sont exécutés lorsque nous exécutons "x.py".
Mais seul 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 lorsqu'une fonction de "x.py" est appelé de y.py).
Lorsque vous exécutez Python de manière interactive, la variable locale __name__
se voit attribuer la valeur __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 attribut __name__
reçoit la valeur __main__
plutôt que son nom réel. du module. De cette manière, les modules peuvent examiner leur propre valeur __name__
pour déterminer eux-mêmes comment ils sont utilisés, que ce soit en tant que prise en charge d'un autre programme ou en tant qu'application principale exécutée à partir de la ligne de commande. Ainsi, l'idiome suivant est assez commun dans les modules Python:
if __== '__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.
Considérer:
if __== "__main__":
main()
Il vérifie si l'attribut __name__
du script Python est "__main__"
. En d'autres termes, si le programme lui-même est exécuté, l'attribut sera __main__
et le programme sera exécuté (dans ce cas, la fonction main()
).
Cependant, si votre script Python est utilisé par un module, tout code en dehors de l'instruction if
sera exécuté. Par conséquent, if \__== "\__main__"
est utilisé uniquement pour vérifier si le programme est utilisé comme un module ou non, et décide donc si le code doit être exécuté.
Avant d'expliquer quoi que ce soit sur if __== '__main__'
il est important de comprendre ce que __name__
est et ce qu'il fait.
Qu'est-ce que
__name__
?
__name__
est un DunderAlias - peut être considéré comme une variable globale (accessible à partir de modules) et fonctionne de manière similaire à global
.
C'est une chaîne (globale comme mentionné ci-dessus) comme indiqué par type(__name__)
(donnant <class 'str'>
), et est un standard intégré pour à la fois Python et Python 2 versions.
Où:
Il peut non seulement être utilisé dans des scripts, mais également dans l'interpréteur et dans les modules/packages.
Interprète:
>>> print(__name__)
__main__
>>>
Script:
fichier_test.py :
print(__name__)
Résultat dans __main__
Module ou package:
quelquefichier.py:
def somefunction():
print(__name__)
fichier_test.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 du module ou du package n'est pas indiqué, mais possède son propre DunderAlias __file__
, qui le permet.
Vous devriez voir que, où __name__
, où il s’agit du fichier principal (ou du programme) sera toujours , retournera __main__
, et s’il s’agit d’un module/Le package, ou tout ce qui est exécuté par un autre script Python, renverra le nom du fichier d'où il provient.
Pratique:
Etre une variable signifie que sa valeur peut être écrasée ("can" ne signifie pas "devrait"), écraser la valeur de __name__
entraînera un manque de lisibilité. . Alors ne le faites pas, pour aucune raison. 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, changer cette valeur par défaut causera plus de confusion, ce qui posera des problèmes plus tard.
exemple:
>>> __= 'Horrify' # Change default from __main__
>>> if __== 'Horrify': print(__name__)
...
>>> else: print('Not Horrify')
...
Horrify
>>>
Il est généralement considéré comme une bonne pratique d’inclure le if __== '__main__'
dans les scripts.
Maintenant, répondez
if __== '__main__'
:
Maintenant nous connaissons le comportement de __name__
les choses deviennent plus claires:
Un if
est une instruction de contrôle de flux qui contient le bloc de code à exécuter si la valeur donnée est true. Nous avons vu que __name__
peut prendre soit __main__
ou le nom du fichier à partir duquel il a été importé.
Cela signifie que si __name__
est égal à __main__
, alors le fichier doit être le fichier principal et doit être en cours d'exécution (ou c'est l'interpréteur), pas un module ou package importé dans le script.
Si effectivement __name__
prend la valeur de __main__
, alors tout ce qui est dans ce bloc de code sera exécuté.
Cela nous indique que si le fichier en cours d'exécution est le fichier principal (ou si vous exécutez directement à partir de l'interpréteur), cette condition doit être exécutée. Si c'est un paquet, alors il ne devrait pas, et la valeur ne 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 communes mais utiles avec __name__
, je vais vous en montrer quelques-unes ici:
Exécution uniquement si le fichier est un module ou un package:
if __!= '__main__':
# Do some useful things
Exécution d'une condition si le fichier est le fichier principal et d'une autre si ce n'est pas le cas:
if __== '__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 utiliser de manière élaborée les 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 s'avérer très utile.
Je pense qu'il est préférable de casser la réponse en profondeur et avec des mots simples:
__name__
: Chaque module de Python a un attribut spécial appelé __name__
. C'est une variable intégrée qui renvoie le nom du module.
__main__
: Comme d'autres langages de programmation, Python possède é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. Vous pouvez utiliser un module Python de deux manières: exécutez-le directement en tant que script ou importez-le. Lorsqu'un module est exécuté en tant que script, son __name__
est défini sur __main__
.
Ainsi, la valeur de l'attribut __name__
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.
C'est un cas particulier lorsqu'un fichier Python est appelé à partir de la ligne de commande. Ceci est généralement utilisé pour appeler une fonction "main ()" ou pour exécuter un autre code de démarrage approprié, comme la gestion des arguments en ligne de commande, par exemple.
Cela pourrait être écrit de plusieurs manières. Un autre est:
def some_function_for_instance_main():
dosomething()
__== '__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 le fait qu'il n'y a rien de "magique" dans if __== '__main__'
. C'est une bonne convention pour invoquer une fonction principale dans les fichiers Python.
Le système (interpréteur Python) fournit un certain nombre de variables pour les fichiers source (modules). Vous pouvez obtenir leurs valeurs quand vous le souhaitez, concentrons-nous donc sur la variable _ NAME _:
Lorsque Python charge un fichier de code source, il exécute tout le code qu'il contient. (Notez qu'il n'appelle pas toutes les méthodes et fonctions définies dans le fichier, mais les définit.)
Avant que l’interprète 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é depuis un autre module, _ NAME _ sera défini sur le nom de ce module.
Donc, dans votre exemple en partie:
if __== "__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 le module directement; 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 ce cas particulier.
J'espère que cela aide.
if __== "__main__":
est fondamentalement l'environnement de script de niveau supérieur et 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 est exécuté. Le __name__
d'un module est défini sur égal à '__main__'
lorsqu'il est lu à partir d'une entrée standard, d'un script ou d'une invite interactive.
if __== "__main__":
# Execute only if run as a script
main()
La raison pour
if __== "__main__":
main()
consiste principalement à éviter les problèmes blocage de l'importation qui pourraient survenir de code importé directement . Vous voulez que main()
s'exécute si votre fichier a été invoqué directement (c'est le cas __== "__main__"
), mais si votre code a été importé, l'importateur doit saisir 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 prenant en charge plusieurs points d'entrée. Vous pouvez exécuter votre programme en utilisant main()
comme point d'entrée , mais vous n'êtes pas obligé de le faire . Alors que setup.py
s'attend à main()
, d'autres outils utilisent d'autres points d'entrée. Par exemple, pour exécuter votre fichier en tant que processus gunicorn
, vous définissez une fonction app()
à la place de main()
. Comme avec setup.py
, gunicorn
importe votre code afin que vous ne souhaitiez rien faire pendant son importation (en raison du problème de verrouillage d'importation).
J'ai lu tellement de choses 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:
L'action import a
exécute en réalité tout ce qui peut être exécuté dans "a"
En raison du point 1, vous pouvez ne pas vouloir que tout soit exécuté dans "a" lors de son importation
Pour résoudre le problème du point 2, python vous permet de mettre une vérification de condition
__name__
est une variable implicite dans tous les modules .py; lorsque a.py est importé, la valeur de __name__
du module a.py est définie sur son nom de fichier "a"; Lorsque a.py est exécuté directement à l'aide de "python a.py", ce qui signifie que a.py est le point d'entrée, la valeur de __name__
du module a.py est définie sur une chaîne __main__
Basé sur le mécanisme selon lequel python définit la variable __name__
pour chaque module, savez-vous comment atteindre le point 3? La réponse est assez facile, non? Mettez une condition if: if __== "__main__": ...
; vous pouvez même mettre si __== "a"
en fonction de vos besoins fonctionnels
La chose importante que python est spéciale au point 4! Le reste n'est que de la logique de base.
Considérer:
print __name__
La sortie pour ce qui précède est __main__
.
if __== "__main__":
print "direct method"
L'instruction ci-dessus est vraie et affiche "méthode directe". Supposons que s'ils importent cette classe dans une autre classe, elle n'imprime pas "méthode directe" car, lors de l'importation, elle définira __equal to "first model name"
.
Vous pouvez rendre le fichier utilisable comme script ainsi que comme 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 __== "__main__":
import sys
fib(int(sys.argv[1]))
Référence: https://docs.python.org/3.5/tutorial/modules.html
Cette réponse est destinée aux Java programmeurs apprenant Python. Chaque fichier Java contient généralement une classe publique. Vous pouvez utiliser cette classe de deux manières:
Appelez la classe à partir d'autres fichiers. Il vous suffit de l'importer dans le programme appelant.
Exécutez la classe de manière autonome, à des fins de test.
Dans ce dernier cas, la classe devrait contenir une méthode publique statique void main (). Dans Python, cette tâche est remplie par l'étiquette définie globalement '__main__'
.
Si ce fichier .py est importé par d'autres fichiers .py, le code sous "l'instruction if" ne sera pas exécuté.
Si ces .py sont exécutés par python this_py.py
sous Shell ou double-cliquez sur Windows. le code sous "l'instruction if" sera exécuté.
Il est généralement écrit pour les tests.
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é directement, indiquant 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 imprimera a, c'est-à-dire le nom du fichier qui est importé.
Donc, pour montrer deux comportements différents du même fichier, c'est un truc couramment utilisé:
# Code to be run when imported into another python file
if __== '__main__':
# Code to be run only when run directly
Nous voyons si __== '__main__':
assez souvent.
Il vérifie si un module est importé ou non.
En d'autres termes, le code dans le bloc if
ne sera exécuté que lorsque le code sera exécuté directement. Ici, directly
signifie 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 __== '__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__
Toutes les réponses ont à peu près expliqué la fonctionnalité. Mais je vais donner un exemple d'utilisation qui pourrait aider à clarifier davantage le concept.
Supposons que vous avez 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 que le reste du code a.py ne soit exécuté, le code du fichier b.py doit être exécuté complètement.
Dans le code b.py, il existe un code exclusif à ce fichier b.py et nous ne souhaitons utiliser aucun autre fichier (autre que le fichier b.py) ayant importé le fichier b.py pour l’exécuter.
C'est 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 ici (a.py est le fichier principal en cours d'exécution), seul le code est exécuté.
C'est simplement le point d'entrée pour exécuter le fichier comme pour la fonction main
dans le langage de programmation C.
Chaque module de python a un attribut appelé nom. La valeur de l'attribut name est "main" lorsque le module s'exécute directement. Sinon, la valeur de nom 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 __== "__main__":
print("Value of __is: ", __name__)
print("Going to call hello_world")
hello_world()
Nous pouvons exécuter cela directement en tant que
python test.py
Sortie
Value of __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__)
Quand vous exécutez ceci
python external_calling.py
Sortie
42
I am inside hello_world
test
Donc, ci-dessus est explicite: lorsque vous appelez test depuis un autre script, if loop name dans test.py ne sera pas exécuté.
Si l'interpréteur python exécute un module particulier, la variable globale __name__
aura la valeur "__main__"
def a():
print("a")
def b():
print("b")
if __== "__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
a
Si vous importez ce fichier, dites A dans le fichier B et exécutez le fichier B, puis if __== "__main__"
dans le fichier A devient faux, ainsi il s’imprimera Vous ne pouvez pas me voir
b