Python2转Python3时str.encode()长度变4致unpack报错求助
哈哈,这个坑我迁移Python2到3的时候踩过!咱们先把问题根源理清楚,再给你解决办法。
问题根源
- 在Python2里,
str本质就是二进制字节序列,你用unpack('H', s1)是直接对这2个字节做16位整数解析,完全没问题。 - 到了Python3,
str变成了Unicode字符序列,而你调用s1.encode()时默认用的是utf-8编码。你的s1是2个Unicode字符,每个字符在utf-8编码下占2个字节,所以encode后总长度变成4,而unpack('H', ...)要求输入必须是刚好2个字节,自然就报错了。
解决方案
你要明确:原来的s1在Python2里是二进制数据(不是文本字符串),所以在Python3里必须把它还原成bytes类型,且保持字节长度不变。具体分两种情况处理:
情况1:已错误将二进制数据转成Python3的str
如果你的s1是从文件/网络读取,或者其他途径变成了Python3的str,那用latin-1编码把它转回bytes——因为latin-1是单字节编码,每个Unicode字符(U+0000到U+00FF)对应唯一的1个字节,能完美还原Python2里的原始字节:
# Python3 代码 import struct s1 = "你的目标字符串" # type为str,len=2 # 用latin-1编码转回bytes,长度保持2 s1_bytes = s1.encode('latin-1') # 现在可以正常unpack了 result = struct.unpack('H', s1_bytes) print(result)
情况2:直接处理二进制数据(推荐做法)
如果是读取文件或者网络数据,直接用二进制模式操作,避免转换成str:
- 读取文件时用
open('file.bin', 'rb'),这样得到的直接是bytes类型; - 网络传输接收的二进制数据,Python3里也会是
bytes类型,直接用struct.unpack即可。
内容的提问来源于stack exchange,提问作者Zheng
相关产品推荐
相关产品推荐

