本文的主要目的是演示如何在 Python 中捕获、存储和显示子进程的输出。
Subprocess 是一个内置的 Python 模块,预装了 Python 安装文件。 它用于通过创建新进程来运行新代码和应用程序,其中给定任务(根据传递的内容)与其进程分开执行。
使用 Subprocess 的主要优点之一是它允许我们从当前编写的程序中启动新程序。
运行此类程序的一个示例是,如果您想从 Git 存储库克隆某个项目,或者可能执行执行其特定任务的 C++ 编译器二进制文件。
假设我们要执行一个用 C++ 编写的程序,其代码如下。
#include
using namespace std;
int main()
{
int rows = 5, count = 0, count1 = 0, k = 0;
for(int i = 1; i <= rows; ++i)
{
for(int space = 1; space <= rows-i; ++space)
{
cout << " ";
++count;
}
while(k != 2*i-1)
{
if (count <= rows-1)
{
cout << i+k << " ";
++count;
}
else
{
++count1;
cout << i+k-2*count1 << " ";
}
++k;
}
count1 = count = k = 0;
cout << endl;
}
return 0;
}
哪个打开独立执行给出以下输出:
现在我们执行使用 Python 编写的程序的编译二进制文件。
import subprocess
p2 = subprocess.Popen("program\\pyramid.exe")
print(p2)
输出:
<Popen: returncode: None args: '....\\program\\pyramid.exe>
1
2 3 2
3 4 5 4 3
4 5 6 7 6 5 4
5 6 7 8 9 8 7 6 5
如上面的代码所示,很明显,我们没有获取字符串,而是获取了 Popen 的实例,这不是理想的情况,因为我们需要字符串的输出来对输出或其他内容执行处理 目的。
必须注意的是,我们看到的金字塔输出不是打印名为 p2 的变量的结果,而是使用 Popen 执行的程序的输出。
可以通过多种方式解决此问题,下面将介绍其中的一些方式。
考虑以下代码:
from subprocess import check_output
out = check_output(["program\\pyramid.exe"])
print(out)
输出:
b' 1 \r\n 2 3 2 \r\n 3 4 5 4 3 \r\n 4 5 6 7 6 5 4 \r\n5 6 7 8 9 8 7 6 5 \r\n'
输出为字节形式,可以使用 decode()
函数轻松将其转换为字符串。
print(out.decode('utf-8'))
输出:
这是我们在名为 out 的字符串变量中所需的输出。
check_output()
函数运行我们想要的命令,并以字节串的形式返回执行程序的命令输出。
然后我们可以使用 decode()
方法将字节字符串转换为普通字符串。 decode()
参数的编码参数可能因输出类型而异。
在我们的例子中,它是 utf-8,但它可能因程序和操作系统而异。
考虑以下代码:
import subprocess
pipe = subprocess.Popen("\\program\\pyramid.exe", stdout=subprocess.PIPE)
text = pipe.communicate()[0]
print(text)
输出:
b' 1 \r\n 2 3 2 \r\n 3 4 5 4 3 \r\n 4 5 6 7 6 5 4 \r\n5 6 7 8 9 8 7 6 5 \r\n'
像以前一样,返回一个字节字符串,可以使用 decode() 函数轻松返回。
print(text.decode('utf-8'))
输出:
除了使用 check_output,我们还可以使用 Popen.communicate()
方法,check_output 的主要优点之一是它允许将 stdout 和 stderr 重定向到我们想要的变量。
Popen 返回 stdout 和 stderr 的元组,因此当您访问 [0] 时,您只是在获取 stdout。 你也可以做文本,err = pipe.communicate()
,然后文本就会有需要的东西。
就像 check_output 一样,Popen.communicate()
也返回一个字节字符串,在将兼容且合适的编码方案传递给 decode 方法后,可以使用 decode 方法轻松将其转换为普通字符串。