从另一个Python脚本运行Python脚本,传入参数

时间:2010-09-23 19:31:12

标签: python

我想从另一个Python脚本运行Python脚本。我想传递变量,就像我使用命令行一样。

例如,我将运行我的第一个脚本,它将迭代值列表(0,1,2,3)并将它们传递给第二个脚本script2.py 0然后script2.py 1等。

我发现Stack Overflow question 1186789这是一个类似的问题,但是ars的答案调用了一个函数,我想运行整个脚本,而不仅仅是一个函数,而balpha的答案调用脚本但没有参数。我将此更改为以下内容作为测试:

execfile("script2.py 1")

但它没有正确接受变量。当我在script2.py中打印出sys.argv时,它是对第一个脚本“['C:\ script1.py']的原始命令调用。

我真的不想更改原始脚本(即我的示例中的script2.py),因为我不拥有它。

我认为必须有办法做到这一点;我很困惑你是怎么做的。

7 个答案:

答案 0 :(得分:280)

尝试使用os.system

os.system("script2.py 1")

execfile不同,因为它旨在在当前执行上下文中运行一系列Python语句。这就是为什么sys.argv没有为你改变的原因。

答案 1 :(得分:87)

这本身就是错误的做法。如果您从另一个Python脚本运行Python脚本,则应该通过Python而不是通过操作系统进行通信:

import script1

在理想的世界中,您可以直接在script1内调用函数:

for i in range(whatever):
    script1.some_function(i)

如有必要,您可以破解sys.argv。使用上下文管理器有一种巧妙的方法可以确保您不进行任何永久性更改。

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)

我认为这比将所有数据传递给操作系统更好;那太傻了。

答案 2 :(得分:80)

理想情况下,您要运行的Python脚本将使用接近结尾的代码进行设置:

def main(arg1, arg2, etc):
    # do whatever the script does


if __name__ == "__main__":
    main(sys.argv[1], sys.argv[2], sys.argv[3])

换句话说,如果从命令行调用模块,它会解析命令行选项,然后调用另一个函数main()来完成实际工作。 (实际参数会有所不同,解析可能会更复杂。)

但是,如果你想从另一个Python脚本调用这样的脚本,你只需import并直接调用modulename.main(),而不是通过操作系统。

os.system将起作用,但它是环形交叉(读取“慢”)的方式,因为你每次都没有葡萄干开始一个全新的Python解释程序。

答案 3 :(得分:38)

子过程模块:
http://docs.python.org/dev/library/subprocess.html#using-the-subprocess-module

import subprocess
subprocess.Popen("script2.py 1", shell=True)

有了这个,你还可以重定向stdin,stdout和stderr。

答案 4 :(得分:33)

我认为好的做法可能是这样的;

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)

根据文件 子进程模块允许您生成新进程,连接到它们的输入/输出/错误管道,并获取它们的返回代码。该模块旨在替换几个较旧的模块和功能:

os.system
os.spawn*
os.popen*
popen2.*
commands.*

使用communic()而不是.stdin.write,.stdout.read或.stderr.read来避免由于任何其他OS管道缓冲区填满和阻止子进程而导致的死锁。 Read Here

答案 5 :(得分:26)

import subprocess
subprocess.call(" python script2.py 1", shell=True)

答案 6 :(得分:3)

如果os.system对你来说不够强大,那就是the subprocess module