python中protobuf和json互相转换应用处理方法
作者:hsy12342611 发布时间:2023-03-15 11:50:55
在实际信息系统开发中,经常会用到各种各样的协议,网络协议常用的有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生成器
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"] = 9999
json_person["name"] = "liudehua"
json_person["sex"] = 1
json_person["addr"] = json_addr
json_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()
#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"] = 9999
json_person["name"] = "liudehua"
json_person["sex"] = 1
json_person["addr"] = json_addr
json_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 = 110
person.name = "Boss"
person.addr.province = "anm"
person.addr.city = "qiuchongtian"
person.addr.county = "ABC"
person.addr.detail = "123"
person.sex = message_pb2.Person.Sex.MAIL
person.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 person1
if __name__ == "__main__":
#构造PB
pb = 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字符串打印输出。
运行结果如下:
来源:https://blog.csdn.net/hsy12342611/article/details/128108829
猜你喜欢
- 学习目的: 掌握文本框的用法 初次接触try…catch…语法 今天内容很轻松,用一个例子,输入年月日,判断输入是否正确 图片如下: 用个
- 本文通过Python3+pyqt5实现了python Qt GUI 快速编程的16章的excise例子。#!/usr/bin/env pyt
- 先写一个批处理文件,给个例子。 代码如下:set rq=%date:~0,10% exp system/system的
- 本文通过实例为大家分享了python实现批量提取指定文件夹下同类型文件,供大家参考,具体内容如下代码import osimport shut
- 训练的时候内存一直在增加,最后内存爆满,被迫中断。后来换了一个电脑发现还是这样,考虑是代码的问题。检查才发现我的代码两次存了loss,只有一
- 基于ASP技术开发Internet/Intranet上的MIS系统是非常方便的,首先是它借用了ADO技术和概念,同时
- 整理了一下python 中文件的输入输出及主要介绍一些os模块中对文件系统的操作。文件输入输出1、内建函数open(file_name,文件
- 这篇是Nicholas讨论如果防止脚本失控的第二篇,主要讨论了如何重构嵌套循环、递归,以及那些在函数内部同时执行很多子操作的函数。基本的思想
- 这里所谓的复杂表单,是指表单中包含多种不同的输入类型,比如下拉列表框、单行文本、多行文本、数值等。在经常需要更换这类表单的场合,需要有一个表
- 本文实例讲述了Python实现将数据框数据写入mongodb及mysql数据库的方法。分享给大家供大家参考,具体如下:主要内容:1、数据框数
- 本来想等到IE8正式发布时再在blog中写段代码,用来提示IE6用户升级到IE8的,不过貌似IE 8已经RTM了,今天又正好看到这个“升级I
- 虽然以前我写过IE6、IE7、IE8共存的解决方案,但是看到IETester这个软件以后那些都已经没有意义了(那些办法副作用比较大,而且实现
- WebSocket 是什么?摘抄网上的一些解释:WebSocket 协议是基于 TCP 的一种新的网络协议。它实现了浏览器与服务器全双工(f
- 登录SYS创建临时表空间/*创建临时表空间 */create temporary tablespace 表空间名 t
- 事件调度sched 模块内容很简单,只定义了一个类。它用来最为一个通用的事件调度模块。class sched.scheduler(timef
- 一、介绍正则表达式各语言都有自己的规范,但是基本都差不多,都是由元字符的组合来进行匹配;由于Nmap内嵌的服务与版本探测是使用的Perl正则
- 去过新浪或者搜狐吗?虽然我们都不愿意看广告,但是它们做广告的技术我们却应该学到手,这不,又一种很流行的做法儿,做成那种两边对称的对联式的广告
- 网页广告 Banner 设计图文手册:采用以下要点来改善你的BANNER。广告并不便宜。 确信你的广告被第一时间读到。使用像这样的Sans
- 在IE浏览器调试代码,我们可以选择使用 IE WebDeveloper但是我个人用惯了ff浏览器下的firebug,所以在网上搜了一下,如果
- Liwu_Items表,CreateTime列建立聚集索引 第一种,sqlserver2005特有的分页语法 代码如下:declare @p