web-dev-qa-db-fra.com

Pourquoi Python exécute-t-il mon module lorsque je l'importe et comment puis-je l'arrêter?

J'ai un programme Python que je construis et qui peut être exécuté de deux manières: la première consiste à appeler "python main.py", qui invite l'utilisateur à entrer de manière conviviale, puis lance le entrée utilisateur à travers le programme. L’autre méthode consiste à appeler "python batch.py ​​- file -", qui passera au-dessus de toute la collecte d’entrée conviviale et exécutera un fichier entier en une seule fois dans le programme.

Le problème est que quand je lance "batch.py", il importe des variables/méthodes/etc de "main.py", et quand il exécute ce code:

import main

à la première ligne du programme, il se trompe immédiatement car il essaie d'exécuter le code dans "main.py".

Comment puis-je empêcher Python d'exécuter le code contenu dans le module "principal" que je suis en train d'importer?

142
Dasmowenator

Parce que c’est ainsi que Python fonctionne: les mots clés tels que class et def ne sont pas des déclarations . Au lieu de cela, ce sont des instructions réelles qui sont exécutées. S'ils n'étaient pas exécutés, votre module serait .. vide :-)

Quoi qu'il en soit, l'approche idiomatique est la suivante:

# stuff to run always here such as class/def
def main():
    pass

if __== "__main__":
   # stuff only to run when not called via 'import' here
   main()

Voir Qu'est-ce que if __== "__main__" pour?

Cela nécessite toutefois un contrôle de la source sur le module en cours de traitement imported.

Bonne codage.

211
user166390

En raison du fonctionnement de Python, il est nécessaire qu’il exécute vos modules lorsqu’il les importe.

Pour empêcher le code dans le module d'être exécuté lors de l'importation, mais uniquement s'il est exécuté directement, vous pouvez le protéger avec ceci if:

if __== "__main__":
    # this won't be run when imported

Vous voudrez peut-être insérer ce code dans une méthode main() afin d'exécuter le fichier directement ou d'importer le module et d'appeler le main(). Par exemple, supposons que cela se trouve dans le fichier foo.py.

def main():
    print "Hello World"

if __== "__main__":
    main()

Ce programme peut être exécuté soit en accédant à python foo.py, soit à partir d'un autre script Python:

import foo

...

foo.main()
46
Jeremy Banks

Utilisez le if __== '__main__' idiome - __name__ est une variable spéciale dont la valeur est '__main__' si le module est exécuté en tant que script et son nom s'il est importé. Alors tu ferais quelque chose comme

# imports
# class/function definitions
if __== '__main__':
    # code here will only run when you invoke 'python main.py'
11
Ismail Badawi

Malheureusement non. Cela fait partie du fonctionnement de la syntaxe d'importation et il est important que ce soit le cas - rappelez-vous que def est réellement exécuté, si Python n'exécutait pas l'importation, vous le seriez bien. , bloqué sans fonctions.

Étant donné que vous avez probablement accès au fichier, vous pourrez peut-être regarder et voir la cause de l'erreur. Il serait peut-être possible de modifier votre environnement pour éviter que l'erreur ne se produise.

4
cwallenpoole

Placez le code dans une fonction et il ne fonctionnera pas avant d'appeler la fonction. Vous devriez avoir une fonction principale dans votre main.py. avec la déclaration:

if __== '__main__':
  main()

Ensuite, si vous appelez python main.py, la fonction main() sera exécutée. Si vous importez main.py, ce ne sera pas le cas. En outre, vous devriez probablement renommer main.py en quelque chose d'autre par souci de clarté.

4
Matt

Vous pouvez écrire votre "main.py" comme ceci:

#!/usr/bin/env python

__all__=["somevar", "do_something"]

somevar=""

def do_something():
    pass #blahblah

if __name__=="__main__":
    do_something()
2
hgoldfish

Il y avait une Python proposition d'amélioration PEP 299 qui visait à remplacer l'idiome if __== '__main__': par def __main__:, mais elle a été rejetée. C'est toujours une bonne lecture pour savoir quoi garder à l'esprit lors de l'utilisation de if __= '__main__':.

1
Paul Tobias