270 votes

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

J'ai un programme Python que je suis en train de construire et qui peut être exécuté de deux façons : la première est d'appeler python main.py qui invite l'utilisateur à saisir des données de manière conviviale, puis exécute les données saisies par l'utilisateur dans le programme. L'autre méthode consiste à appeler python batch.py _-file-_ qui passera en revue toutes les entrées amicales et fera passer un fichier entier d'entrées par le programme en une seule fois.

Le problème est que lorsque je lance batch.py il importe certaines variables/méthodes/etc. de main.py et lorsqu'il exécute ce code :

import main

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

Comment empêcher Python d'exécuter le code contenu dans le fichier main que j'importe ?

4voto

tobias.pal Points 71

Il y a eu une proposition d'amélioration de Python PEP 299 qui visait à remplacer la if __name__ == '__main__': idiome avec def __main__: mais elle a été rejetée. C'est néanmoins une bonne lecture pour savoir ce qu'il faut garder à l'esprit lors de l'utilisation de la if __name__ = '__main__': .

3voto

hgoldfish Points 111

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

2voto

user5673662 Points 11

J'ai fait un test simple :

test.py

x = 1
print("1, has it been executed?")

def t1():
     print("hello")
     print("2, has it been executed?")

def t2():
     print("world")
     print("3, has it been executed?")

def main():
     print("Hello World")
     print("4, has it been executed?")

print("5, has it been executed?")
print(x)

# while True:
# t2()

if x == 1:
     print("6, has it been executed?")

test2.py

import test

Lors de l'exécution de test2.py, le résultat de l'exécution :

1, has it been executed?

5, has it been executed?

1

6, has it been executed?

Conclusion : Lorsque le module importé n'ajoute pas de if __name__=="__main__": Le code du module importé qui n'est pas dans la fonction est exécuté séquentiellement, et le code de la fonction n'est pas exécuté lorsqu'il n'est pas appelé.

en outre:

def main():
    # Put all your code you need to execute directly when this script run directly.
    pass

if __name__ == '__main__':
    main() 
else:
    # Put functions you need to be executed only whenever imported

0voto

Stefano Crema Points 1

Une erreur mineure qui peut se produire (en tout cas cela m'est arrivé), en particulier lors de la distribution de scripts/fonctions python qui effectuent une analyse complète, est d'appeler la fonction directement à la fin du fichier .py de la fonction. Les seules choses que l'utilisateur devait modifier étaient les fichiers d'entrée et les paramètres. En procédant ainsi lors de l'importation, la fonction s'exécute immédiatement. Pour un comportement correct, il suffit de supprimer l'appel interne à la fonction et de le réserver au fichier/fonction/partie du code qui l'appelle réellement.

0voto

wayne Points 1

Une autre option consiste à utiliser une variable d'environnement binaire, par exemple "run_code". Si run_code = 0 (False), structurez main.py pour contourner le code (mais la fonction temporairement contournée sera toujours importée en tant que module). Plus tard, lorsque vous serez prêt à utiliser la fonction importée (devenue un module), définissez la variable d'environnement run_code = 1 (True). Utilisez la commande os.environ pour définir et récupérer la variable binaire, mais assurez-vous de la convertir en un entier lors de la récupération (ou restructurez l'instruction if pour lire une valeur de chaîne),

dans main.py :

import os

#set environment variable to 0 (False):
os.environ['run_code'] = '0'

def binary_module():
    #retrieve environment variable, convert to integer
    run_code_val = int(os.environ['run_code'] )

    if run_code_val  == 0:
        print('nope. not doing it.')
    if run_code_val == 1:
        print('executing code...')
        # [do something]

...dans le script qui charge main.py :

import os,main

main.binary_module() 

OUTPUT : non, je ne le fais pas.

# now flip the on switch!
os.environ['run_code'] = '1'
main.binary_module()

OUTPUT : exécution du code...

*Note : Le code ci-dessus suppose que main.py et tout script qui l'importe existent dans le même répertoire.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X