¿Cuál es la mejor manera de llamar a un script desde otro script?

Tengo un script llamado test1.py que no está en un módulo. Simplemente tiene un código que debe ejecutarse cuando se ejecuta el script. No hay funciones, clases, métodos, etc. Tengo otra secuencia de comandos que se ejecuta como un servicio. Quiero llamar a test1.py desde el script que se ejecuta como un servicio.

Por ejemplo:

Archivo test1.py

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

Archivo service.py

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

Soy consciente de un método que es abrir el archivo, leer los contenidos y, básicamente, evaluarlos. Estoy asumiendo que hay una mejor manera de hacer esto. O al menos eso espero.

La forma habitual de hacer esto es algo como lo siguiente.

test1.py

 def some_func(): print 'in test 1, unproductive' if __name__ == '__main__': # test1.py executed as script # do something some_func() 

service.py

 import test1 def service_func(): print 'service func' if __name__ == '__main__': # service.py executed as script # do something service_func() test1.some_func() 

Esto es posible en Python 2 usando

 execfile("test2.py") 

Consulte la documentación para el manejo de los espacios de nombres, si es importante en su caso.

Sin embargo, debe considerar utilizar un enfoque diferente; Tu idea (por lo que puedo ver) no se ve muy limpia.

De otra manera:

Archivo test1.py:

 print "test1.py" 

Archivo service.py:

 import subprocess subprocess.call("test1.py", shell=True) 

La ventaja de este método es que no tiene que editar un script de Python existente para colocar todo su código en una subrutina.

Documentación: Python 2 , Python 3

Si quieres que test1.py permanezca ejecutable con la misma funcionalidad que cuando se llama dentro de service.py, haz algo como:

test1.py

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

service.py

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

No deberías estar haciendo esto. En su lugar, haz:

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

Use import test1 para el primer uso: ejecutará el script. Para invocaciones posteriores, trate el script como un módulo importado y llame al método reload(test1) .

Cuando se ejecuta la reload(module) :

  • El código de los módulos de Python se vuelve a comstackr y el código a nivel de módulo se vuelve a ejecutar , definiendo un nuevo conjunto de objetos que están vinculados a nombres en el diccionario del módulo. La función init de los módulos de extensión no se llama

Se puede utilizar una comprobación simple de sys.modules para invocar la acción apropiada. Para seguir refiriéndose al nombre del script como una cadena ( 'test1' ), use el componenteimport ()’ .

 import sys if sys.modules.has_key['test1']: reload(sys.modules['test1']) else: __import__('test1') 
 import os os.system("python myOtherScript.py arg1 arg2 arg3") 

Usando OS puedes hacer llamadas directamente a tu terminal. Si desea ser aún más específico, puede concatenar su cadena de entrada con variables locales, es decir.

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

¿Por qué no solo importar test1? Cada script de python es un módulo. Una mejor manera sería tener una función, por ejemplo, main / run en test1.py, importar test1 y ejecutar test1.main (). O puede ejecutar test1.py como un subproceso.

Este es un ejemplo con la biblioteca de 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_)