online - Ejecute un script de Python desde otro script de Python, pasando en args
python interpreter pycharm (7)
Esta pregunta ya tiene una respuesta aquí:
Quiero ejecutar un script de Python desde otro script de Python. Quiero pasar variables como lo haría usando la línea de comandos.
Por ejemplo, ejecutaría mi primer script que iteraría a través de una lista de valores (0,1,2,3) y los pasaría al segundo script script2.py 0
luego script2.py 1
, etc.
Encontré el SO 1186789 que es una pregunta similar, pero la respuesta de ars llama a una función, donde, como quiero ejecutar todo el script, no solo una función, y la respuesta de balpha llama al script pero sin argumentos. Alteré esto a algo como el siguiente a modo de prueba:
execfile("script2.py 1")
Pero no está aceptando variables adecuadamente. Cuando sys.argv
el sys.argv
en script2.py, es la llamada de comando original al primer script "[''C: / script1.py''].
Realmente no quiero cambiar el script original (es decir, script2.py en mi ejemplo) ya que no lo poseo.
Me imagino que debe haber una manera de hacer esto, estoy confundido de cómo lo haces.
Creo que la buena práctica puede ser algo como esto;
import subprocess
cmd = ''python script.py''
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True)
out, err = p.communicate()
result = out.split(''/n'')
for lin in result:
if not lin.startswith(''#''):
print(lin)
de acuerdo con la documentación El módulo de subproceso le permite generar nuevos procesos, conectarse a sus tuberías de entrada / salida / error y obtener sus códigos de retorno. Este módulo pretende reemplazar varios módulos y funciones más antiguos:
os.system
os.spawn*
os.popen*
popen2.*
commands.*
Use comunicarse () en lugar de .stdin.write, .stdout.read o .stderr.read para evitar interbloqueos debido a que cualquiera de los otros buffers de tuberías del sistema operativo llenen y bloqueen el proceso secundario. Leer aquí
Esto es intrínsecamente lo que se debe hacer. Si está ejecutando un script de Python desde otro script de Python, debe comunicarse a través de Python en lugar de hacerlo a través del sistema operativo:
import script1
En un mundo ideal, podrá llamar directamente a una función dentro de script1
:
for i in range(whatever):
script1.some_function(i)
Si es necesario, puede hackear sys.argv
. Hay una forma clara de hacerlo utilizando un administrador de contexto para asegurarse de que no realice cambios permanentes.
import contextlib
@contextlib.contextmanager
def redirect_argv(num):
sys._argv = sys.argv[:]
sys.argv=[str(num)]
yield
sys.argv = sys._argv
with redirect_argv(1):
print(sys.argv)
Creo que esto es preferible a pasar todos sus datos al sistema operativo y viceversa; eso es simplemente tonto
Idealmente, la secuencia de comandos de Python que desea ejecutar se configurará con un código como este cerca del final:
def main(arg1, arg2, etc):
# do whatever the script does
if __name__ == "__main__":
main(sys.argv[1], sys.argv[2], sys.argv[3])
En otras palabras, si se llama al módulo desde la línea de comando, analiza las opciones de la línea de comando y luego llama a otra función, main()
, para hacer el trabajo real. (Los argumentos reales variarán y el análisis puede ser más complicado).
Sin embargo, si desea llamar a un script de este tipo desde otro script de Python, simplemente puede import
y llamar a modulename.main()
directamente, en lugar de pasar por el sistema operativo.
os.system
funcionará, pero es la forma indirecta (lea "lento") de hacerlo, ya que está iniciando un proceso de intérprete de Python completamente nuevo cada vez que no tenga pasas.
Módulo de subproceso:
http://docs.python.org/dev/library/subprocess.html#using-the-subprocess-module
import subprocess
subprocess.Popen("script2.py 1", shell=True)
Con esto, también puedes redireccionar stdin, stdout y stderr.
Si os.system no es lo suficientemente potente para usted, existe el módulo de subproceso .
Trate de usar os.system
:
os.system("script2.py 1")
execfile
es diferente porque está diseñado para ejecutar una secuencia de sentencias de Python en el contexto de ejecución actual . Es por eso que sys.argv
no cambió para ti.
import subprocess
subprocess.call(" python script2.py 1", shell=True)