¿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. Solo tiene código que debe ejecutarse cuando se ejecuta el script en sí. No hay funciones, clases, métodos, etc. Tengo otro script que se ejecuta como un servicio. Quiero llamar 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 el contenido, y básicamente evaluarlo. Soy asumiendo que hay una mejor manera de hacer esto. O al menos eso espero.

Author: martineau, 2009-07-27

8 answers

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()
 217
Author: ars,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-07-27 07:12:30

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, deberías considerar usar un enfoque diferente; tu idea (por lo que puedo ver) no se ve muy limpia.

 108
Author: balpha,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-08-04 15:32:17

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 Python existente para poner todo su código en una subrutina.

Documentación: Python 2, Python 3

 52
Author: Dick Goodwin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-02-08 20:17:52

Si quieres test1.py para permanecer ejecutable con la misma funcionalidad que cuando se llama dentro service.py luego haga 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
 16
Author: Michael Schneider,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-07-27 07:11:51

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

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()
 10
Author: thedz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-07-27 07:06:37

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

Cuando se ejecuta reload(module):

  • El código de los módulos Python se recompila 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

A comprobación simple de sys.modules se puede utilizar para invocar la acción apropiada. Para seguir refiriéndose al nombre del script como una cadena ('test1'), utilice el 'importar()' construido.

import sys
if sys.modules.has_key['test1']:
    reload(sys.modules['test1'])
else:
    __import__('test1')
 7
Author: gimel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-07-27 07:32:00
import os

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

Usando so 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)
 5
Author: Alex Mapley,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-12-05 08:07:00

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

 1
Author: Anurag Uniyal,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-02-26 05:23:26