web-dev-qa-db-fra.com

Quel est le meilleur moyen d'appeler un script à partir d'un autre script?

J'ai un script nommé test1.py qui n'est pas dans un module. Il a juste du code qui doit être exécuté lorsque le script lui-même est exécuté. Il n'y a pas de fonctions, classes, méthodes, etc. J'ai un autre script qui s'exécute en tant que service. Je souhaite appeler test1.py à partir du script exécuté en tant que service.

Par exemple:

Fichier test1.py

print "I am a test"
print "see! I do nothing productive."

Fichier service.py

# Lots of stuff here
test1.py # do whatever is in test1.py

Je connais une méthode qui consiste à ouvrir le fichier, à en lire le contenu et à l’évaluer. Je suppose qu'il existe un meilleur moyen de le faire. Ou du moins je l'espère.

235
Josh Smeaton

La façon habituelle de procéder est la suivante.

test1.py

def some_func():
    print 'in test 1, unproductive'

if __== '__main__':
    # test1.py executed as script
    # do something
    some_func()

service.py

import test1

def service_func():
    print 'service func'

if __== '__main__':
    # service.py executed as script
    # do something
    service_func()
    test1.some_func()
228
ars

Ceci est possible dans Python 2 en utilisant

execfile("test2.py")

Voir documentation pour le traitement des espaces de noms, si cela est important pour votre cas.

Cependant, vous devriez envisager une approche différente. votre idée (d'après ce que je peux voir) n'a pas l'air très propre.

114
balpha

Autrement:

Fichier test1.py:

print "test1.py"

Fichier service.py:

import subprocess

subprocess.call("test1.py", Shell=True)

L'avantage de cette méthode est qu'il n'est pas nécessaire de modifier un script Python existant pour mettre tout son code dans un sous-programme.

Documentation: Python 2 , Python 3

58
Dick Goodwin

Si vous voulez que test1.py reste exécutable avec les mêmes fonctionnalités que lorsqu'il est appelé dans service.py, procédez comme suit:

test1.py

def main():
    print "I am a test"
    print "see! I do nothing productive."

if __== "__main__":
    main()

service.py

import test1
# lots of stuff here
test1.main() # do whatever is in test1.py
17
Michael Schneider

Vous ne devriez pas faire ça. Au lieu de cela, faites:

test1.py:

 def print_test():
      print "I am a test"
      print "see! I do nothing productive."

service.py

#near the top
from test1 import print_test
#lots of stuff here
print_test()
11
thedz

Utilisez import test1 pour la 1ère utilisation - le script sera exécuté. Pour les appels ultérieurs, traitez le script en tant que module importé et appelez la méthode reload(test1) .

Lorsque reload(module) est exécuté:

  • Le code des modules Python est recompilé et le code au niveau du module est réexécuté, définissant un nouvel ensemble d’objets liés aux noms du dictionnaire du module. La fonction init des modules d'extension n'est pas appelée 

Une simple vérification de sys.modules peut être utilisée pour appeler l'action appropriée. Pour continuer à faire référence au nom du script sous forme de chaîne ('test1'), utilisez le paramètre 'import ()' builtin.

import sys
if sys.modules.has_key['test1']:
    reload(sys.modules['test1'])
else:
    __import__('test1')
7
gimel
import os

os.system("python myOtherScript.py arg1 arg2 arg3")  

En utilisant os, vous pouvez appeler directement sur votre terminal. Si vous voulez être encore plus spécifique, vous pouvez concaténer votre chaîne d'entrée avec des variables locales, c'est-à-dire.

command = 'python myOtherScript.py ' + sys.argv[1] + ' ' + sys.argv[2]
os.system(command)
5
Alex Mapley

Pourquoi ne pas simplement importer test1? Chaque script python est un module. Un meilleur moyen serait d’avoir une fonction, par exemple main/run dans test1.py, importez test1 et exécutez test1.main (). Ou vous pouvez exécuter test1.py en tant que sous-processus.

1
Anurag Uniyal

Voici un exemple avec la bibliothèque subprocess:

import subprocess

python_version = '3'
path_to_run = './'
py_name = '__main__.py'

# args = [f"python{python_version}", f"{path_to_run}{py_name}"]  # Avaible in python3
args = ["python{}".format(python_version), "{}{}".format(path_to_run, py_name)]

res = subprocess.Popen(args, stdout=subprocess.PIPE)
output, error_ = res.communicate()

if not error_:
    print(output)
else:
    print(error_)
1
Benyamin Jafari

J'ai trouvé cet exemple simple sur http://hplgit.github.io/primer.html/doc/pub/tech/._tech-solarized012.html pour appeler un script python depuis un autre, même lorsque vous devez spécifier plusieurs arguments

import subprocess
cmd = 'python train_frcnn.py --input_weight_path model_frcnn.hdf5 -o simple -p take2.csv'
subprocess.call(cmd, Shell=True)
0
Shreya