从另一个Python脚本运行Python脚本并传递参数
我想从一个Python脚本运行另一个Python脚本。我想像在命令行中那样传递变量。
比如,我会运行第一个脚本,它会遍历一个值的列表(0,1,2,3),然后把这些值传给第二个脚本,比如 script2.py 0
,接着是 script2.py 1
,依此类推。
我找到了一条在Stack Overflow上的问题1186789,这个问题和我想做的很相似,但里面的回答是调用一个函数,而我想运行整个脚本,而不仅仅是一个函数。还有一个回答是调用脚本,但没有传递参数。我把这个改成了下面这样的测试:
execfile("script2.py 1")
但是它没有正确接受变量。当我在script2.py中打印 sys.argv
时,它显示的是最初调用第一个脚本的命令 "['C:\script1.py']"。
我其实不想更改原来的脚本(也就是我例子中的script2.py),因为我并不拥有它。
我觉得一定有办法做到这一点,只是我不太明白该怎么做。
6 个回答
这样做本质上是错误的。如果你想从一个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解释器进程,完全没有必要。
试试用 os.system
这个方法:
os.system("script2.py 1")
execfile
是不一样的,因为它是用来在当前的执行环境中运行一系列的Python语句。这就是为什么 sys.argv
对你来说没有变化的原因。