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

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

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

我找到了堆栈溢出问题1186789,这是一个类似的问题,但ars的答案调用了一个函数,因为我想运行整个脚本,而不仅仅是一个函数,而balpha的答案调用了脚本,但没有参数。我将其更改为如下所示作为测试:

execfile("script2.py 1")

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

我真的不想改变原来的脚本(即script2.py在我的例子中),因为我不拥有它。

我想一定有办法做到这一点;我只是不明白你是怎么做到的。

1020777 次浏览

尝试使用os.system:

os.system("script2.py 1")

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

< p >子过程模块:< br > http://docs.python.org/dev/library/subprocess.html#using-the-subprocess-module < / p >
import subprocess
subprocess.Popen("script2.py 1", shell=True)

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

这本来就是错误的做法。如果你从另一个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)

我认为这比将所有数据传递给操作系统更可取;这太愚蠢了。

理想情况下,你想要运行的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解释器进程。

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

我认为好的实践应该是这样的;

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.*

使用communication()而不是.stdin。写,.stdout。Read或.stderr。读取以避免由于任何其他OS管道缓冲区填充并阻塞子进程而导致的死锁。 在这里阅读 < / p >