如何在Python中正确解码Protobuf二进制消息?ParseFromString返回整数
Protobuf编码解码问题:ParseFromString返回整数而非原结构
处理Protobuf项目时,需要将SHCoefficients结构编码为二进制,再解码恢复含数据的原结构(pb2实例或可读字符串均可),但执行测试代码时,SerializeToString()正常返回二进制消息,ParseFromString()却返回一个整数,不是预期的结构。
测试代码
import coeff_pb2 as pb2 coeff = pb2.SHCoefficients() # SHCoefficients是结构名称 # 为结构添加数据 x = coeff.SerializeToString() y = coeff.ParseFromString(x)
问题原因
ParseFromString()方法的返回值是成功解析的字节数,它不会返回新的Protobuf结构实例,而是直接在调用该方法的对象内部填充解析后的数据。
解决方法
方法1:复用原对象解析
如果不需要保留原对象的初始数据,可以直接在原对象上调用ParseFromString(),解析完成后原对象就会被更新为解码后的结构:
import coeff_pb2 as pb2 coeff = pb2.SHCoefficients() # 为结构添加测试数据 coeff.week_nr = 2024 coeff.sow = 12345.67 coeff.clm.extend([0.1, 0.2, 0.3]) # 编码为二进制 binary_data = coeff.SerializeToString() # 解析到原对象(这里会覆盖原数据,但因为是序列化自己,数据一致) parsed_bytes = coeff.ParseFromString(binary_data) # 直接使用原对象即可访问解码后的数据 print("解析的字节数:", parsed_bytes) print("week_nr:", coeff.week_nr) print("clm列表:", coeff.clm)
方法2:创建新对象解析
如果需要保留原对象的数据,创建一个新的SHCoefficients实例来执行解析操作:
import coeff_pb2 as pb2 coeff = pb2.SHCoefficients() # 为结构添加测试数据 coeff.week_nr = 2024 coeff.sow = 12345.67 # 编码为二进制 binary_data = coeff.SerializeToString() # 创建新实例解析 new_coeff = pb2.SHCoefficients() parsed_bytes = new_coeff.ParseFromString(binary_data) # 新实例就是解码后的结构 print("解析的字节数:", parsed_bytes) print("week_nr:", new_coeff.week_nr) print("sow值:", new_coeff.sow)
输出可读字符串
如果需要将Protobuf结构转为可读字符串,直接打印对象即可,或者使用MessageToJson()转为JSON格式:
# 打印可读文本格式 print(new_coeff) # 转为JSON格式 from google.protobuf.json_format import MessageToJson json_str = MessageToJson(new_coeff) print(json_str)
附:proto文件内容
syntax = "proto3"; message SHCoefficients { uint32 week_nr = 1; double sow = 2; uint32 time_reference = 3; uint32 lmax = 4; uint32 n_coff = 5; repeated double clm = 6; repeated double slm = 7; }
内容的提问来源于stack exchange,提问作者Domingo Blavriano
相关产品推荐
相关产品推荐

