Python2串口读取工具迁移至Python3后数据格式异常如何解决?
核心原因
pyserial在Python3中serial.read()返回的本身就是未做任何修改的原始二进制数据,你观察到的差异只是字节对象的默认打印规则和Python2不同,数据本身没有被转换:
- Python2中
read()返回str类型,打印时会直接把每个字节当做ASCII字符输出,不可打印的控制字符就会导致终端乱码,和实际串口返回的二进制内容对应 - Python3中
read()返回独立的bytes类型,默认打印时为了避免乱码和歧义,会把不可打印字符转义为十六进制表示,同时加b前缀标识类型,实际内存中存储的二进制数据和串口读到的完全一致,没有额外处理。
适配方案
打印适配
如果需要和Python2完全一致的打印效果,不要用默认的print()方法,直接写入标准输出的二进制缓冲区即可:
import sys class TED(object): def __init__(self, device): self.port = serial.Serial(device, 19200, timeout=0) self.escape_flag = False def poll(self): self.port.write(b'\xAA') return self.decode(self.port.read(4096)) def decode(self, raw): # 输出效果和Python2完全一致,包含控制字符导致的终端乱码 sys.stdout.buffer.write(b'raw=' + raw + b'\n')
业务逻辑适配
raw本身就是原始二进制数据,不需要额外转换即可直接做后续处理,只需要调整Python2遗留的字节操作语法即可:
- 取单字节的整数值:Python2用
ord(raw[i]),Python3直接用raw[i]即可返回0-255的整数 - 字节拼接:直接用
+操作bytes对象,和Python2中str拼接逻辑一致 - 要查看十六进制格式的原始数据:调用
raw.hex()方法即可得到连续的十六进制字符串
内容的提问来源于stack exchange,提问作者mike
相关产品推荐
相关产品推荐

