调用其他程序
掌握
subprocess模块调用外部程序的方法能获取外部程序的输出、错误信息和返回码
区分阻塞调用和非阻塞调用的适用场景
核心讲解
Python 可以调用系统命令、其他脚本、可执行文件,实现和外部程序的联动,subprocess 是官方推荐的标准模块,替代了旧的 os.system、commands 等模块。
(1)核心函数:subprocess.run ()
最常用的调用方式,阻塞执行,直到外部程序结束才返回结果。
基本参数:
args:命令,可以是列表(推荐)或字符串capture_output=True:捕获标准输出和错误输出text=True:输出为字符串,默认是字节shell=True:通过系统 shell 执行命令,Windows 下常用cwd:指定工作目录timeout:超时时间,超时抛出异常
返回对象属性:
returncode:返回码,0 表示成功,非 0 表示失败stdout:标准输出内容stderr:错误输出内容
(2)Popen:非阻塞调用
subprocess.Popen 是底层实现,启动程序后不等待,程序在后台运行,可以后续交互,适合需要并行执行、实时交互的场景。
常用方法:
poll()检查是否结束、wait()等待结束、communicate()发送输入并获取输出
(3)使用建议
优先用列表形式传命令,避免 shell 注入风险
需要捕获输出就加
capture_output=True, text=True简单命令用
run(),复杂交互、后台运行用Popen()
代码示例
import subprocess
# ===== 1. 基础调用(run) =====
# 调用系统命令(列表形式,推荐)
result = subprocess.run(["python", "--version"], capture_output=True, text=True)
print("返回码:", result.returncode)
print("输出:", result.stdout.strip())
print("错误:", result.stderr)
# Windows下调用dir命令(需要shell=True)
# result = subprocess.run("dir", shell=True, capture_output=True, text=True, encoding="gbk")
# print(result.stdout)
# ===== 2. 调用其他Python脚本 =====
# 假设有一个test.py脚本
# result = subprocess.run(
# ["python", "test.py"],
# capture_output=True,
# text=True,
# cwd="./scripts" # 指定工作目录
# )
# print(result.stdout)
# ===== 3. 带超时的调用 =====
try:
result = subprocess.run(
["ping", "baidu.com", "-n", "2"],
capture_output=True,
text=True,
timeout=5
)
print(result.stdout)
except subprocess.TimeoutExpired:
print("命令执行超时")
# ===== 4. Popen 后台运行 =====
# 启动程序,不阻塞
proc = subprocess.Popen(
["python", "-c", "import time; time.sleep(3); print('done')"],
capture_output=True,
text=True
)
print("程序已启动,继续执行其他代码...")
# 检查是否结束
if proc.poll() is None:
print("程序还在运行中...")
# 等待结束,获取输出
stdout, stderr = proc.communicate()
print("程序结束,输出:", stdout.strip())
print("返回码:", proc.returncode)
常见误区
shell 注入风险:使用
shell=True时,如果命令包含用户输入的内容,可能被注入恶意命令,优先用列表形式输出乱码:Windows 系统命令默认 GBK 编码,不指定编码会乱码,加
encoding="gbk"或设置text=True配合编码路径问题:调用的程序不在系统 PATH 里,要用绝对路径;相对路径是相对于当前工作目录
Popen 资源泄漏:Popen 对象用完要确保关闭,或者用
with语句管理忽略返回码:不能只看输出,要判断
returncode是否为 0,确认命令执行成功
课后练习
调用系统 ping 命令,ping 百度,捕获并输出结果
编写脚本,调用另一个 Python 脚本,并获取它的输出
用 Popen 启动一个耗时程序,轮询检查运行状态,结束后输出结果
尝试调用系统计算器程序(calc)

