python if invalid - Que fait si __name__ == “__main__”: do?





13 Answers

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

syntax fonction class

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



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



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.




__name__ simplement, __name__ est une variable définie pour chaque script qui définit si le script est exécuté en tant que module principal ou s'il est exécuté 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 dit 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 pas être utilisé comme une bibliothèque.

Supposons que vous écriviez un script Python très performant 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__": . Tandis qu'en C / C ++, vous devez 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.




Considérer:

if __name__ == "__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__ , le programme sera donc 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é. Ainsi, if \__name__ == "\__main__" est utilisé uniquement pour vérifier si le programme est utilisé comme module ou non, et décide par conséquent si le code doit être exécuté.




Le système (interpréteur Python) fournit un certain nombre de variables pour les fichiers source (modules). Vous pouvez obtenir leurs valeurs à tout moment, alors concentrons-nous sur la variable / attribut __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 d'exécuter le fichier de code source, l'interpréteur définit cependant 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 la valeur "__main__" .

S'il 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 le module directement; le bloc de code ne sera pas exécuté 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.




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.




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




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




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.




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

C'est donc ce que cette ligne de code vérifie. S'il s'agit du fichier principal (c.-à-d. 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é.




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__





Related