subprocess模块使用介绍

本文将会介绍Python中的subprocess模块的使用。

笔者在文章NLP(九十九)大模型的数学能力微调及测评中使用大模型生成Python代码,并且要将执行后的结果再次送入大模型进行问答。期间,笔者使用了subprocess模块来获取Python代码运行结果。

subprocess模块是python从2.4版本开始引入的模块。主要用来取代一些旧的模块方法,如os.system、os.spawn、os.popen、commands.*等。subprocess通过子进程来执行外部指令,并通过input/output/error管道,获取子进程的执行的返回信息。

本文将会结合笔者自己的需求,来介绍subprocess模块的一些使用方法。

简单例子

可以使用subprocess模块中的call方法或者Popen类来执行Linux中的命令,并获取其输出内容,效果同直接运行Linux命令一样。

1
2
3
4
5
6
7
8
9
10
11
12
import subprocess

# 运行Linux命令
rc = subprocess.call(["ls","-l"])
# out = subprocess.call("ls -l", shell=True)

# 运行Linux命令,并获取其输出的内容
child = subprocess.Popen(["ls","-l"], stdout=subprocess.PIPE)
child.wait()
t = child.communicate()
print("command finished!")
print('stdout: ', t)

运行Python脚本

可以使用subprocess模块来运行Python代码或脚本,并获取其运行结果。

例如我们有temp.py脚本,内容如下:

1
2
3
4
5
# -*- coding: utf-8 -*-
# @file: temp.py
a = 1
b = 1
print(f"{a} / {b} = {a / b}")

使用subprocess模块运行该脚本,代码如下:

1
2
3
4
5
import subprocess

python_code_run = subprocess.run(['python3', "temp.py"], stdout=subprocess.PIPE)
python_code_execution = python_code_run.stdout.decode('utf-8')
print(python_code_execution)

输出如下:

1
1 / 1 = 1.0

获取状态码

如果Python代码有错误,即Python脚本执行错误时,我们也能使用状态码来判断Python脚本是否执行成功。

我们将temp.py脚本修改如下:

1
2
3
4
5
# -*- coding: utf-8 -*-
# @file: temp.py
a = 1
b = 0
print(f"{a} / {b} = {a / b}")

使用subprocess模块运行该脚本,代码如下:

1
2
3
4
5
import subprocess

python_code_run = subprocess.run(['python3', "temp.py"], stdout=subprocess.PIPE)
python_code_execution = python_code_run.stdout.decode('utf-8')
print("return code: ", python_code_run.returncode)

输出如下:

1
2
3
4
5
return code:  1
Traceback (most recent call last):
File "/Users/admin/PycharmProjects/env_test/subprocess_test/temp.py", line 5, in <module>
print(f"{a} / {b} = {a / b}")
ZeroDivisionError: division by zero

超时控制

如果Python代码中存在超时,比如大模型生成了带有死循环的代码,那么也可以使用timeout参数来控制运行结果。

我们将temp.py脚本修改如下(代码带死循环):

1
2
3
4
5
6
7
# -*- coding: utf-8 -*-
# @file: temp.py
a = 1
b = 1
print(f"{a} / {b} = {a / b}")
while True:
print(a, b)

使用subprocess模块运行该脚本,代码如下:

1
2
3
4
5
import subprocess

python_code_run = subprocess.run(['python3', "temp.py"], stdout=subprocess.PIPE, timeout=5)
python_code_execution = python_code_run.stdout.decode('utf-8')
print("python_code_execution: ", python_code_execution)

输出结果如下:

1
2
3
Traceback (most recent call last):
......
subprocess.TimeoutExpired: Command '['python3', 'temp.py']' timed out after 5 seconds

如果不加入timeout参数,则使用subprocess模块运行该脚本将不会停止。

总结

本文结合笔者在执行大模型生成的Python代码运行情况,介绍了subprocess模块的一些简单使用方法,希望能对读者有所帮助~


subprocess模块使用介绍
https://percent4.github.io/subprocess模块使用介绍/
作者
Jclian91
发布于
2024年6月19日
许可协议