一、subprocess
模块的核心作用
1. 功能定义
- 用途:启动并管理外部进程(如执行系统命令、运行其他可执行程序)
- 典型场景:
- 在Python中调用命令行工具(如
ping
、ffmpeg
) - 执行Shell脚本或其他语言编写的程序
- 获取外部程序的输出或错误信息
- 在Python中调用命令行工具(如
2. 与multiprocessing/threading/asyncio模块的关联
- 共同点:都涉及进程操作
- 本质区别:
multiprocessing
/threading
/asyncio
:管理Python自身的并发执行subprocess
:控制外部独立程序的执行
二、subprocess
与其他模块的对比
特性 | subprocess | multiprocessing | threading /asyncio |
---|---|---|---|
目标对象 | 外部进程(如ls 、ping ) | Python子进程 | Python线程/协程 |
内存隔离性 | 完全独立(外部程序) | 独立(但可共享数据) | 共享进程内存 |
通信方式 | 标准输入/输出/错误流 | Queue/Pipe等 | 直接共享变量 |
适用场景 | 调用非Python程序 | Python代码并行计算 | Python内部的并发任务 |
三、subprocess
核心用法详解
1. 基础案例:执行系统命令
import subprocess
# 执行`ls -l`命令(Linux/Mac),Windows可换成`dir`
result = subprocess.run(["ls", "-l"], capture_output=True, text=True)
print("命令返回值:", result.returncode) # 0表示成功
print("标准输出:\n", result.stdout)
print("错误输出:", result.stderr)
2. 代码解释
subprocess.run()
:同步执行命令,等待其完成- 参数说明:
["ls", "-l"]
:命令列表(避免Shell注入风险)capture_output=True
:捕获输出(等价于stdout=subprocess.PIPE, stderr=subprocess.PIPE
)text=True
:以字符串形式返回输出(否则返回bytes)
3. 进阶用法:管道通信
# 执行`find . -name "*.py"`查找所有Python文件
find_process = subprocess.Popen(
["find", ".", "-name", "*.py"],
stdout=subprocess.PIPE,
text=True
)
# 将结果传递给`wc -l`统计行数
wc_process = subprocess.Popen(
["wc", "-l"],
stdin=find_process.stdout, # 连接上一个进程的输出
stdout=subprocess.PIPE,
text=True
)
# 获取最终结果
output, error = wc_process.communicate()
print("找到的Python文件数量:", output.strip())
四、与multiprocessing
的对比案例
场景:同时运行Python函数和外部程序
import multiprocessing
import subprocess
import time
# Python函数任务
def python_task():
time.sleep(2)
print("Python任务完成")
# 外部程序任务(执行系统命令)
def external_task():
subprocess.run(["sleep", "2"]) # Linux/Mac的`sleep`命令
print("外部程序任务完成")
if __name__ == "__main__":
# 创建两个进程:一个执行Python函数,一个执行外部命令
p1 = multiprocessing.Process(target=python_task)
p2 = multiprocessing.Process(target=external_task)
p1.start()
p2.start()
p1.join()
p2.join()
print("所有任务完成")
代码逻辑
主进程
├─ 子进程1:执行Python函数(通过multiprocessing)
└─ 子进程2:执行外部命令(通过subprocess)
五、subprocess
与asyncio
的协作
异步执行外部命令
import asyncio
async def async_command():
# 创建异步子进程
process = await asyncio.create_subprocess_exec(
"ping", "-c", "4", "www.baidu.com",
stdout=asyncio.subprocess.PIPE,
stderr=asyncio.subprocess.PIPE
)
# 异步读取输出
stdout, stderr = await process.communicate()
print(f"Ping结果:\n{stdout.decode()}")
asyncio.run(async_command())
六、总结
- 何时用
subprocess
:- 需要调用非Python程序(如系统工具、其他语言编写的程序)
- 需要与命令行工具交互(如调用
git
、docker
)
- 与其他模块的关系:
- 可以组合使用:例如用
multiprocessing
创建多个进程,每个进程用subprocess
调用外部程序 subprocess
启动的进程与Python主进程完全独立,而multiprocessing
的子进程受Python控制
- 可以组合使用:例如用
通过合理选择工具,可以实现:
- Python内部并行 →
multiprocessing
/threading
/asyncio
- 与外部系统交互 →
subprocess