
本文详解如何使用 python 切片语法从原始 bytes 对象中安全、高效地提取连续字节子序列,并生成符合 crc 校验函数要求的新 bytes 实例。
本文详解如何使用 python 切片语法从原始 bytes 对象中安全、高效地提取连续字节子序列,并生成符合 crc 校验函数要求的新 bytes 实例。
在处理串口通信(如 Modbus RTU 协议)时,常需从完整帧中剥离有效载荷部分进行 CRC-16 校验。根据问题描述,设备发送的 14 字节帧结构为:[Sync][Data_0..Data_10][CRC_H][CRC_L],其中索引 1 至 11(含)共 11 个字节为待校验的数据区(注意:Python 索引从 0 开始,rxData[1:12] 表示从第 1 位到第 12 位前一位,即包含索引 1~11 共 11 个元素)。
正确提取方式是使用bytes 切片(slice)——bytes 是不可变序列类型,支持与 list 相同的切片语法,且切片结果仍为 bytes 类型,可直接传入 check_crc() 等函数:
# ✅ 正确:提取 rxData 中索引 1 ~ 11(共11字节)构成新 bytes 对象 newData = rxData[1:12]
⚠️ 注意事项:
- rxData[1:12] 是左闭右开区间:包含索引 1,不包含索引 12;
- 起始索引 1 对应 sync byte 后的第一个数据字节;
- 结束索引 12 确保覆盖到索引 11(即第 12 个字节的前一个),恰好截取 11 字节;
- 切片返回全新 bytes 对象,原 rxData 不受影响;
- 若实际接收长度不足 14 字节(如通信异常),建议先校验 len(rxData) >= 14,避免 IndexError。
将该语句插入原代码 ### Missing code... 处后,完整关键段落如下:
# ...(前面的串口读取代码保持不变)
print("Now show only bytes 1 to 11 of rxData")
for i in range(1, 12):
print(hex(rxData[i]), end=" ")
print()
#####################
# ✅ 插入此处:提取字节 1~11 构造新 bytes
newData = rxData[1:12]
#####################
print("\nThe 'newData' type is ", type(newData), " and length is ", len(newData))
print("'newData' - ", [hex(b) for b in newData])
print("\ncheck if newData CRC is OK")
if not check_crc(newData):
print("CRC is NOT OK")
else:
print("CRC is OK!")
运行后,newData 将准确持有 [0x0d, 0x77, 0x02, 0x01, 0x01, 0x12, 0x33, 0x30, 0x2e, 0x38, 0x39] —— 即原始帧中剔除首字节(sync)和末两字节(CRC)后的纯数据区,完全满足 modbus_crc.check_crc() 的输入要求。
总结:Python 的 bytes[start:end] 切片是处理二进制协议帧解析最简洁、最 Pythonic 的方式,无需转换为 list 或 bytearray(除非需后续修改),兼具性能与可读性。










