在Windows上使用子进程运行Python脚本

57 投票
8 回答
152098 浏览
提问于 2025-04-15 11:51

有没有简单的方法可以在Windows/Linux/OS X上运行Python脚本?

在后两种系统上,subprocess.Popen("/the/script.py")可以正常工作,但在Windows上我遇到了以下错误:

Traceback (most recent call last):
  File "test_functional.py", line 91, in test_functional
    log = tvnamerifiy(tmp)
  File "test_functional.py", line 49, in tvnamerifiy
    stdout = PIPE
  File "C:\Python26\lib\subprocess.py", line 595, in __init__
    errread, errwrite)
  File "C:\Python26\lib\subprocess.py", line 804, in _execute_child
    startupinfo)
WindowsError: [Error 193] %1 is not a valid Win32 application

monkut的评论: 这个用例不太清楚。为什么要用subprocess来运行一个Python脚本?有没有什么原因让你不能直接导入这个脚本并调用需要的函数?

我写了一个快速脚本来测试一个Python命令行工具的整体功能(在不同平台上测试它)。基本上,它需要在一个临时文件夹中创建一堆文件,运行这个脚本,然后检查文件是否被正确重命名。

我本可以直接导入这个脚本并调用函数,但因为它依赖于sys.argv并使用sys.exit(),我需要做一些像这样的事情……

import sys
import tvnamer
sys.argv.append("-b", "/the/folder")
try:
    tvnamer.main()
except BaseException, errormsg:
    print type(errormsg)

另外,我想捕获标准输出和错误输出,以便在出现问题时进行调试。

当然,更好的方法是以更易于单元测试的方式编写脚本,但这个脚本基本上已经“完成”,我正在进行最后一轮测试,以便进行“1.0”版本发布(之后我会进行重写和重构,这样会更整洁、更易于测试)

总的来说,找到sys.executable变量后,简单地将脚本作为一个进程运行要容易得多。我本可以把它写成一个shell脚本,但那样就不能跨平台了。最终的脚本可以在这里找到。

8 个回答

7

没错,subprocess.Popen(cmd, ..., shell=True) 的确很好用。在Windows系统上,.py 文件后缀会被识别,所以会调用Python来处理这个文件(在类Unix系统上则是用常规的shebang)。环境变量中的路径决定了哪些文件可以被找到。所以,传给 Popen 的第一个参数其实就是 脚本的名字

subprocess.Popen(['myscript.py', 'arg1', ...], ..., shell=True)
26

这样做怎么样:

import sys
import subprocess

theproc = subprocess.Popen("myscript.py", shell = True)
theproc.communicate()                   # ^^^^^^^^^^^^

这段代码是告诉 subprocess 使用操作系统的命令行来打开你的脚本,适用于任何可以在 cmd.exe 中直接运行的东西。

另外,这个方法会在系统的路径中查找 "myscript.py" 文件,这样做可能是有好处的。

80

刚刚发现了 sys.executable - 这是当前Python程序的完整路径,可以用来运行脚本(而不是依赖于shbang,这在Windows上显然是行不通的)

import sys
import subprocess

theproc = subprocess.Popen([sys.executable, "myscript.py"])
theproc.communicate()

撰写回答