Protobuf Python读取二进制文件赋值给repeated bytes对象报错
问题描述
Protobuf定义
syntax = "proto3"; message Message { repeated bytes data = 1; }
出错的Python代码
import test_pb2 message = test_pb2.Message() with open("test.dat", mode='rb') as file: message.data.extend(file.read())
报错信息
Traceback (most recent call last): File "./test.py", line 7, in <module> message.data.extend(file.read()) TypeError: 48 has type int, but expected one of: bytes
对比的正常代码
x = list() with open("test.dat", mode='rb') as file: x.extend(file.read())
问题:Protobuf的repeated对象与普通列表行为不一致,该如何解决?
解决方法
这是因为file.read()在二进制模式下返回的是bytes对象,Python中bytes是可迭代类型,迭代它会逐个返回单个字节对应的整数(比如报错里的48就是字符'0'的ASCII值)。
普通列表的extend方法会直接把这些整数加入列表,但Protobuf的repeated bytes字段要求每个元素必须是完整的bytes对象,而非单个字节的整数,因此抛出类型错误。
根据需求选择以下两种方案:
- 将整个文件内容作为单个bytes元素加入
如果你的需求是把文件的全部内容作为data字段的一个元素存储,使用append方法而非extend:
import test_pb2 message = test_pb2.Message() with open("test.dat", mode='rb') as file: message.data.append(file.read())
- 将文件内容拆分为单个字节的bytes元素
如果确实需要把每个字节作为独立的bytes元素存入data字段,需要把每个整数转换为长度为1的bytes对象:
import test_pb2 message = test_pb2.Message() with open("test.dat", mode='rb') as file: message.data.extend(bytes([b]) for b in file.read())
内容的提问来源于stack exchange,提问作者user180574
相关产品推荐
相关产品推荐

