You need to enable JavaScript to run this app. 用plistlib解析system_profiler生成plist取serial_number报'int'不可下标
优惠活动
大模型
产品
解决方案
定价
更多

用plistlib解析system_profiler生成plist取serial_number报'int'不可下标

报错根源定位

报错'int' object is not subscriptable和你推测的“取值层级逻辑错误”无关,问题出在生成plist文件的步骤逻辑完全错位:

  • 执行subprocess.check_output(cmd)拿到的plist变量,是system_profiler直接输出的、已经是合法plist格式的二进制字节流,不是Python内存中的结构化对象
  • 你错误地把这堆原始字节流,当成普通Python对象传给plistlib.dump(plist, fp)写入文件——plistlib.dump的作用是把内存里的Python字典/数组序列化成plist格式,不是帮你存储已经是plist格式的原始字节
  • 这步操作写出来的hardware.plist是完全损坏的非标准文件,后续用plistlib.load读取时解析出来的结构完全偏离预期,走到索引取值的步骤碰到int类型的值,才会触发“int对象不能用下标访问”的报错。
修正方案

逻辑校准要点

  1. 系统输出的原始plist字节流,如果要落盘,直接按二进制写入即可,不需要走plistlib.dump的序列化流程
  2. 解析plist时不需要绕路读损坏的文件,直接把原始字节流传给plistlib.loads在内存中解析即可,减少不必要的IO开销
  3. 你原本写的取值路径pl[0]['_items'][0]['serial_number']是完全符合给出的合法plist结构的,不需要修改取值逻辑。

修正后可运行的代码

import subprocess
import plistlib

def get_serial_number():
    cmd = ['system_profiler', 'SPHardwareDataType', '-xml']
    # 获取system_profiler输出的原生plist二进制内容
    raw_plist = subprocess.check_output(cmd)
    
    # 需要落盘存文件的话,直接写原始字节即可
    with open('hardware.plist', 'wb') as fp:
        fp.write(raw_plist)
    
    # 直接内存解析plist内容,不需要读本地文件
    parsed_data = plistlib.loads(raw_plist)
    # 原取值路径逻辑正确,直接用即可
    serial = parsed_data[0]['_items'][0]['serial_number']
    return serial

额外提示:之前生成的损坏plist文件可以先删掉再跑修正后的代码,避免旧文件残留导致误判。

内容的提问来源于stack exchange,提问作者rynoknows

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.11.08 09:54:02