python3 - python__name__ variable




Que fait si__name__== “__main__”: do? (18)

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

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

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

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

python mycode.py

L'espace de nom global autrement anonyme a reçu la valeur '__main__' pour son __name__ .

Ainsi, y compris les lignes finales

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

entraînera l'exécution de la fonction main 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()

Que fait le if __name__ == "__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 importé 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 écriviez 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 au bas:

do_important()

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

~$ python important.py

Le problème

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

import important

Lors de l’importation, la fonction do_important serait appelée. Vous devriez donc probablement commenter votre appel de fonction, do_important() , situé au bas de la page.

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

Une meilleure façon

La variable __name__ pointe vers l’espace de nommage où que se trouve l’interprète Python.

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 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 __name__ == "__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).

Une façon encore meilleure

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 à mesure que nous développons et testons 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 __name__ == '__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 classes) d'être appelé lors de l'exécution d'un autre module '__main__' , c'est-à-dire

import important
important.main()

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

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

if __name__ == '__main__':
    main()

si nom == ' main ':

Nous voyons si __name__ == '__main__':assez 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 s'il est exécuté 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__

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


__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 le fait qu'il n'y a rien de "magique" à propos de if __name__ == '__main__' . C'est une bonne convention pour invoquer une fonction principale dans les fichiers Python.


Considérer:

print __name__

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

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

La déclaration ci-dessus est vraie et affiche "méthode directe" . Supposons que s'ils importent cette classe dans une autre classe, la "méthode directe" n'est pas imprimée car, lors de l'importation, il définira __name__ equal to "firstmodel name" .


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 __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 lors de l'importation. Les opérations de ab sont donc exécutées avant le reste de celles de xy . Une fois terminé avec ab , il continue avec xy .

L'interprète __name__ scripts exécutés avec __name__ . Quel que soit le nom que vous avez choisi, l'interpréteur l'appelle "__main__" , ce qui en fait le script maître ou "home" auquel il est renvoyé après l'exécution d'un script externe.

Tout autre script appelé à partir de ce script "__main__" se voit attribuer son nom de fichier sous le nom __name__ (par exemple, __name__ == "ab.py" ). Par conséquent, la ligne if __name__ == "__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 par eux-mêmes jusqu'à ce qu'ils soient appelés. Ce que l'interprète pourrait dire s'il marmonnait tout seul:

  • Ouvrez xy.py en tant que fichier 'home'; appelez-le "__main__" dans la variable __name__ .
  • Importez et ouvrez 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 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 déclaration if . Eh bien, la condition est remplie (la variable __name__ a été définie sur "__main__" ), je vais donc entrer dans la fonction main() et imprimer ' fonction principale: c'est ici que se trouve l'action '.

Les deux lignes du bas signifient: "S'il s'agit du "__main__" ou" home ", exécutez la fonction appelée main() ". C'est pourquoi vous verrez une def main(): block up top, 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 plus d'instructions. 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() 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é de manière externe. Alors vous vous demandez peut-être encore une 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 qui n'est pas contenu dans une fonction main() . Si vous êtes habitué (comme je le suis à mes débuts en programmation) à créer des scripts en ligne qui font exactement ce dont vous avez besoin, et que 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 est probable 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 que vous mettez en majuscule le troisième mot d'une chaîne de texte donnée; créez un tableau NumPy à partir d'une liste de nombres et leur quadrature; ou détruisez 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, cela a été marqué comme une copie de celle-ci , ce qui, à mon avis, est une erreur.)


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 __name__ == '__main__':
    print "Hello World again from %s!" % __name__

Leur exécution 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.

$ 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__" .


La raison pour

if __name__ == "__main__":
    main()

vise principalement à éviter les problèmes de verrouillage des importations qui pourraient résulter de l’ importation directe du code . Vous voulez que main() exécuté si votre fichier a été __name__ == "__main__" directement (c'est le cas __name__ == "__main__" ), mais si votre code a été importé, l'importateur doit saisir votre code à partir du véritable 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 ce n’est pas obligatoire . Alors que setup.py attend main() , d’autres outils utilisent des points d’entrée alternatifs. Par exemple, pour exécuter votre fichier en tant que processus gunicorn , vous définissez une fonction app() au lieu d'un main() . Tout comme avec setup.py , gunicorn importe votre code afin que vous ne vouliez rien faire pendant son importation (en raison du problème de verrouillage d'importation).


Lorsque l'interpréteur Python lit un fichier source, il exécute tout le code qu'il contient.

Avant d'exécuter le code, il définira 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 la variable spéciale __name__ sur la valeur "__main__" . Si ce fichier est importé depuis un autre module, __name__ sera défini sur le nom du module.

Dans le cas de votre script, supposons qu’il s’exécute comme fonction principale, par exemple, 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écute l'instruction d' import et charge ces modules. Il évaluera ensuite le bloc def créant un objet fonction et une variable appelée myfunction qui pointe vers l’objet fonction. Il lira ensuite l'instruction if et verra que __name__ est égal à "__main__" et exécutera donc le bloc indiqué ici.

Une des raisons est que parfois vous écrivez un module (un fichier .py ) où il peut être exécuté directement. Alternativement, il peut également être importé et utilisé dans un autre module. En effectuant la vérification principale, vous ne pouvez exécuter ce code que lorsque vous souhaitez exécuter le module en tant que programme, sans l'exécuter lorsque quelqu'un souhaite simplement importer votre module et appeler vos fonctions eux-mêmes.

Voir cette page pour plus de détails.

Note (par Stainsor): Si vous mettez du code avant les définitions de fonctions, il sera exécuté avant.

print("This code executes before main.") 

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

def functionB():
    print("Function B")

if __name__ == '__main__':
    functionA()
    functionB()

Si ce module est bien principal, ce code a pour résultat:

This code executes before main. 
Function A 
Function B

Si ce module n'est pas principal, vous obtenez:

This code executes before main. 

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() est implicitement tout le code 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), __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 diverses définitions de fonctions et de classes seront importées et son code de niveau supérieur sera exécuté, mais le code figurant dans le corps alors de la clause if ci-dessus ne sera pas exécuté comme condition. n'est pas rencontré. 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 __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è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 place:

python two.py

Vous recevez

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


Quand il y a certaines instructions dans notre module ( M.py ) que nous voulons exécuter quand il sera exécuté en tant que main (non importé), nous pouvons placer ces instructions (tests-case, instructions print) sous this if block.

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

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


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


if __name__ == "__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é. __name__ 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 __name__ == "__main__":
    # Execute only if run as a script
    main()

if __name__ == "__main__" est la partie qui s'exécute lorsque le script est exécuté à partir de la ligne de commande (à l'aide de), à ​​l'aide d'une commande telle que python myscript.py .


Récemment, je suis tombé sur cette idée en créant une classe de python (apprentissage en profondeur) et, à ma connaissance, et en accord avec les explications énumérées ci-dessus, je vais élaborer.

__name__=="__main__"

Comme parfois, nous construisons une classe dans un fichier .py et définissons de nombreuses fonctions dans cette classe. mais nous ne voulons pas traiter toutes ces fonctions de classe dans un seul but. par exemple, pour créer une classe et définir des fonctions pour la création de données (fichiers .npy) et d’autres pour le chargement de données. donc si nous définissons

__name__=="__main__"

xxx = nom_classe ()

xxx.create_data ()

Cela signifie que si nous appelons le fichier .py, il ne créera que des données et ne traitera pas d'autres fonctions de classe. d'autres fonctions de classe (chargement de données) peuvent également être importées par d'autres classes.


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.pysous 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 va imprimer un , 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 __name__ == '__main__':
    # Code to be run only when run directly

J'ai lu beaucoup 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:

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

  2. En raison du point 1, vous pouvez ne pas vouloir 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 modules .py; Quand un fichier.py est importé, la valeur du __name__module a.py est définie sur son nom de fichier "a"; quand 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 du __name__module a.py est définie sur une chaîne__main__

  5. Selon le 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 facile, non? Mettez un si la condition: if __name__ == "__main__": ...; vous pouvez même mettre si en __name__ == "a"fonction de vos besoins fonctionnels

Le point important du python est le point 4! Le reste n'est que logique de base.





idioms