如何格式化subprocess.check_output输出并追加到Python列表
问题原因
- 字节串转换逻辑错误:
subprocess.check_output()默认返回bytes类型结果,直接调用str(data)转换时,会自动在结果首尾添加字节串标记b'和',你拿到的不是子进程输出的原始文本,这是后续替换、分割操作异常、#2位置无输出的核心原因。如果系统默认编码和子进程输出编码不匹配,直接强转还会引入乱码、不可见控制字符,导致print输出被截断。 - 字符串处理逻辑粗暴:全局替换所有
[、]的方式容错性极差,一旦值本身包含方括号就会出现误删,且对于结构化的嵌套数组格式,完全不需要手动做全局替换。 - 列表操作存在冗余和隐患:循环逐元素
append效率偏低,且使用list作为变量名会覆盖Python内置的list类型,容易触发难以排查的异常。另外你当前的subprocess.check_output(path, args)传参方式不符合API要求,正常需要把执行路径和参数拼成列表作为第一个参数传入,否则会触发参数错误。
修复实现
1. 正确读取子进程输出
先把字节串按对应编码解码为普通字符串,跨平台场景优先用utf-8,Windows中文环境如果出现乱码可以替换为gbk:
import subprocess # 按列表传入执行路径和参数,避免shell注入风险 raw_output = subprocess.check_output([your_exec_path, arg1, arg2]) # 解码为普通字符串,同时去掉首尾的换行、空白字符 datastring = raw_output.decode("utf-8").strip()
如果你的Python版本>=3.6,也可以直接给check_output传入encoding参数,直接返回字符串结果,省去手动解码步骤:
datastring = subprocess.check_output( [your_exec_path, arg1, arg2], encoding="utf-8" ).strip()
2. 解析嵌套数组格式的内容
优先方案:结构化解析(推荐)
如果子进程输出是标准JSON格式(字符串值带双引号,例如[["Val1"],["Val2"],["Val3"]]),直接用标准库json解析,不需要做任何手动字符串替换,准确率最高:
import json # 解析后得到原生嵌套列表对象 nested_result = json.loads(datastring) # 提取内层值,得到扁平化的[Val1, Val2, Val3]列表 value_list = [item[0] for item in nested_result if item]
兼容方案:纯文本处理
如果输出不是标准JSON,值没有引号包裹(例如[[Val1],[Val2],[Val3]]),再做针对性的字符串处理,不要全局替换方括号:
# 去掉最外层的一对方括号 core_content = datastring[1:-1].strip() value_list = [] for block in core_content.split(","): # 仅移除每个值块前后的方括号和空白,不会影响值内部的字符 val = block.strip().strip("[]").strip() value_list.append(val)
3. 高效追加到目标列表
直接用列表内置的extend()方法一次性追加所有元素,比循环append执行效率更高,代码更简洁:
# 不要用list作为变量名,避免覆盖内置类型 target_list = [Name, ID] # 一次性追加所有解析出来的值 target_list.extend(value_list)
验证说明
修复后你在#1位置打印的datastring就是子进程输出的原始文本,不会带b'前缀,处理后#2位置可以正常输出清洗后的字符串,最终target_list的结构为[Name, ID, Val1, Val2, Val3],符合预期。
内容的提问来源于stack exchange,提问作者Jakob Kessler
相关产品推荐
相关产品推荐

