如何解析Protobuf文件中缺失引号的字符串字段?
解决Protobuf字符串字段被解析为整数的问题
嘿,我来帮你搞定这个Protobuf解析的小麻烦!你遇到的情况大概率是两种原因之一:要么是你的Protobuf定义里type字段被错误设置成了枚举/整数类型,要么是文本格式的Protobuf(textproto)里字符串字段没加引号,导致解析器误判。下面给你几个针对性的解决方案:
1. 先检查并修正Protobuf定义文件
这是最根本的解决办法,如果你的.proto文件里type字段本来就应该是字符串,却被定义成了枚举或者整数,那肯定会出问题。
比如错误的定义可能是这样的:
// 错误:把type定义成枚举 enum LayerType { CONVOLUTION = 4; } message Layer { LayerType type = 1; }
你需要把它改成字符串类型:
// 正确:type定义为字符串 message Layer { string type = 1; }
改完之后重新生成Python代码(执行protoc --python_out=. your_proto_file.proto),再重新解析,就能正确识别CONVOLUTION为字符串了。
2. 如果无法修改定义,从枚举值反向映射回名称
如果type字段确实是枚举类型,解析后得到的数值4其实是CONVOLUTION对应的枚举值,那你可以通过Protobuf的枚举工具方法把数值转成对应的名称:
import caffe_quant_pb2 as cq # 假设你已经解析得到了layer对象 layer = cq.Layer() # 解析后得到的type是数值4 print(layer.type) # 输出 4 # 用Name()方法反向获取枚举名称 type_name = cq.LayerType.Name(layer.type) print(type_name) # 输出 "CONVOLUTION"
要是你的Protobuf版本比较旧,Name()方法不好用,可以试试这个方式:
# 通过枚举描述器获取名称 enum_value_descriptor = cq.LayerType.DESCRIPTOR.values_by_number[layer.type] type_name = enum_value_descriptor.name print(type_name) # 输出 "CONVOLUTION"
3. 预处理文本格式,给无引号的字符串加引号
如果是因为你的textproto文件格式不规范(字符串字段没加引号),导致解析器把它当成了整数,那可以先手动预处理文本,给type字段的值加上引号再解析:
import re from google.protobuf import text_format import caffe_quant_pb2 as cq # 读取原始的textproto文件 with open("your_layer_config.textproto", "r") as f: raw_content = f.read() # 用正则匹配type字段,给值加上引号 # 匹配格式类似 "type: CONVOLUTION" 的行,替换成 "type: "CONVOLUTION"" processed_content = re.sub(r'(type:\s*)([A-Z_]+)', r'\1"\2"', raw_content) # 解析处理后的内容 layer = cq.Layer() text_format.Merge(processed_content, layer) print(layer.type) # 输出 "CONVOLUTION"
这个方法适合临时修复格式不规范的文件,长期来看还是建议统一规范textproto的格式哦。
内容的提问来源于stack exchange,提问作者Lolo
相关产品推荐
相关产品推荐

