从Python2.x迁移到3.8.6,串口数值列表如何转byte literal
关于byte literal的核心概念
你疑惑的byte literal本质是Python3中专用于存储原始二进制字节序列的不可变数据类型
最直观的标识就是这类字面量带有
b前缀,例如b'\x40\x00\x99',每个存储单元严格对应0-255范围内的单个字节,完全没有普通字符串自带的Unicode编码/解码逻辑,这也是pyserial要求串口写入入参必须是这类对象的核心原因——避免发送的字节内容被隐式编码规则扭曲。
实际开发中提到的“可通过串口发送的byte literal”范围会更宽泛:不管是硬编码带b前缀的固定字面量,还是动态生成的类字节结构对象,只要符合字节序列的格式要求,都能被串口接口正常接收,不需要刻意用硬编码的b前缀格式写死内容。
原代码迁移的最优实现方案
原Python2的代码失效本质是Python3的类型系统做了强约束:Python2中ser.write()可以直接接收0-255范围的单个整数作为入参,但Python3版本的pyserial严格要求写入参数必须是类字节对象,不支持直接传单个整数或普通字符串,这才导致原来循环逐字节写入的逻辑完全跑不通。
- 最高效简洁的转换方式:直接通过
bytes()构造函数把整数列表转成符合要求的字节序列,一次性完成写入,无需保留原来的逐字节循环
示例代码:numbers = [0x40, 0x00, 0x99, 0x54, 0x78, 0x13] # 直接生成可被串口接收的字节序列 send_data = bytes(numbers) ser.write(send_data) - 避坑提示:
- 用
bytes()转换时,列表内每个元素的取值必须严格在0-255区间,超出范围会直接抛出ValueError,这个内置校验能帮你在发送前就发现数值异常,大幅减少串口乱码的排查成本。 - 不要走把列表转成普通字符串再编码的弯路(比如
str(numbers).encode()),这种方式最终发送的是列表文本的ASCII编码内容,和你要发送的原始hex字节完全不一致。 - 如果发送内容需要后续动态修改,可以用
bytearray(numbers)替代bytes()生成可变字节序列,同样可以直接传给ser.write(),无需额外格式转换。
- 用
内容的提问来源于stack exchange,提问作者belieber88
相关产品推荐
相关产品推荐

