python中protobuf和json互相转换应用
创始人
2024-04-14 17:36:23
0

      在实际信息系统开发中,经常会用到各种各样的协议,网络协议常用的有http,tcp,udp等,传输数据格式协议有json,xml,TLV等。本节将给大家介绍一种节省带宽数据协议,谷歌的ProtoBuf协议,该协议由于是开源免费的,有多种语言的调用接口,比如常见C,C++,java,Python,C#,PHP ... 所以国内很多公司都在使用。

      本人所在项目引擎使用C++语言开发,外部输入的protobuf字节流在内部都是使用C++来处理,上次客户端想要用他们的数据来演示效果,让我去客户现处理客户数据,然后导入我们引擎进行效果展示。客户现场数据是excel文件,出差时没有相关的处理工具,本人只好现场开发,提取客户excel中的数据,转换成json,再转换成我们引擎能够识别的ProtoBuf字节流。所以在此记录一下python中protobuf和json的相互转换的处理方法。

protobuf目前有proto2和proto3两个版本,本文所介绍的是基于proto3,在Python 3.6.9环境下运行。

目录

1.ProtoBuf中定义字段与各语言类型对应表

 2.ProtoBuf使用方法

2.1 下载安装protobuf生成器

2.2 定义protobuf格式的应用协议

2.3 生成协议调用api

2.4 调用

3. Json转Protobuf

4. Protobuf转Json


1.ProtoBuf中定义字段与各语言类型对应表

 2.ProtoBuf使用方法

2.1 下载安装protobuf生成器

protobuf生成器可以通过源码编译得到,也可以下载别人编译好的应用程序

GitHub上下载地址如下

GitHub - protocolbuffers/protobuf: Protocol Buffers - Google's data interchange format

2.2 定义protobuf格式的应用协议

下面以公司为业务构造协议,举例如下:

message.proto

syntax = "proto3";message Empty {}message Address {string province = 1;string city = 2;string county = 3;string detail = 4;
}message Person {int32 id = 1;string name = 2;Sex  sex = 3;Address  addr = 4;string email = 5;string phone = 6;enum Sex {MAIL   = 0;FEMAIL = 1;}
}message Company {string name = 1;repeated Person employee = 2;
}

2.3 生成协议调用api

在Python中,生成方式如下:

/home/test/protobuf/bin/protoc -I=/home/test/Python  --python_out=/home/test/Python   message.proto

或者

/home/test/protobuf/bin/protoc --proto_path=/home/test/Python  --python_out=/home/test/Python   message.proto

附C++生成方式如下:

/home/test/protobuf/bin/protoc -I=/home/test/cpp  --cpp_out=/home/test/cpp   message.proto 

或者
/home/test/protobuf/bin/protoc --proto_path=/home/test/cpp  --cpp_out=/home/test/cpp   message.proto 

说明:
-I  或者  --proto_path用来指定proto接口定义文件所在路径

--python_out表示生成Python调用的接口

--cpp_out表示生成C++调用的接口

2.4 调用

引入protobuf库和2.3生成的接口,就可以进行自己的业务开发了

3. Json转Protobuf

调用举例如下:

#coding=utf-8
import message_pb2
from google.protobuf import json_format
import json#json转PB
def jsonToPB():json_addr = {}json_addr["province"] = "shanxisheng"json_addr["city"] = "shangluoshi"json_addr["county"] = "luonanxian"json_addr["detail"] = "guchengzhenliyuancunsanzu"json_person = {}json_person["id"] = 9999json_person["name"] = "liudehua"json_person["sex"] = 1json_person["addr"] = json_addrjson_person["email"] = "123456789@163.com"json_person["phone"] = "859348598948656"strjson = json.dumps(json_person, indent=4)print(strjson)json_to_pb = json_format.Parse(strjson, message_pb2.Person())print(json_to_pb.SerializeToString())if __name__ == "__main__":print("=============Json to PB==========")jsonToPB()

说明:如上先使用json.dumps将字典打包成json字符串,然后使用json_format.Parse将json字符串转换为ProtoBuf对象,然后将ProtoBuf对象序列化为字节流打印输出。

运行结果如下:

 

4. Protobuf转Json

调用代码如下:

#coding=utf-8
import message_pb2
from google.protobuf import json_format
import json#PB转json字符串
def pbToJson(pb):strjson = json_format.MessageToJson(pb)print(strjson)def buildPB():person = message_pb2.Person()person.id = 110person.name = "Boss"person.addr.province = "anm"person.addr.city = "qiuchongtian"person.addr.county = "ABC"person.addr.detail = "123"person.sex = message_pb2.Person.Sex.MAILperson.email = "rulaifo@qq.com"person.phone = "75211234567890"#PB对象序列化为字节流pb1 = person.SerializeToString()person1 = message_pb2.Person()#字节流流构造PB对象person1.ParseFromString(pb1)com = message_pb2.Company()com.name = 'USA'idlist = [111, 222, 222]for id in idlist:per = com.employee.add()per.id = id print(com)   print(person1)return person1if __name__ == "__main__":#构造PBpb = buildPB()print("=============PB to Json==========")pbToJson(pb)

说明:程序中使用message_pb2.Person()初始化得到一个protobuf对象person,然后给对象person各个属性赋值,然后将person序列化为pb1,使用message_pb2.Person()构造另一个对象

person1,person1使用person序列化后的pb1初始化,此时person1和person具有相同的属性。

使用message_pb2.Company()构造一个公司对象com,然后给属性赋值。最后使用json_format.MessageToJson将protobuf类型的person对象转化为json字符串打印输出。

运行结果如下:

 

相关内容

热门资讯

不能访问光猫的的管理页面 光猫是现代家庭宽带网络的重要组成部分,它可以提供高速稳定的网络连接。但是,有时候我们会遇到不能访问光...
银河麒麟V10SP1高级服务器... 银河麒麟高级服务器操作系统简介: 银河麒麟高级服务器操作系统V10是针对企业级关键业务...
【NI Multisim 14...   目录 序言 一、工具栏 🍊1.“标准”工具栏 🍊 2.视图工具...
Android|无法访问或保存... 这个问题可能是由于权限设置不正确导致的。您需要在应用程序清单文件中添加以下代码来请求适当的权限:此外...
北信源内网安全管理卸载 北信源内网安全管理是一款网络安全管理软件,主要用于保护内网安全。在日常使用过程中,卸载该软件是一种常...
​ToDesk 远程工具安装及... 目录 前言 ToDesk 优势 ToDesk 下载安装 ToDesk 功能展示 文件传输 设备链接 ...
AWSECS:访问外部网络时出... 如果您在AWS ECS中部署了应用程序,并且该应用程序需要访问外部网络,但是无法正常访问,可能是因为...
AWSElasticBeans... 在Dockerfile中手动配置nginx反向代理。例如,在Dockerfile中添加以下代码:FR...
AsusVivobook无法开... 首先,我们可以尝试重置BIOS(Basic Input/Output System)来解决这个问题。...
APK正在安装,但应用程序列表... 这个问题可能是由于以下原因导致的:应用程序安装的APK文件可能存在问题。设备上已经存在同名的应用程序...