python中protobuf和json互相转换应用

news2024/11/27 9:42:50

      在实际信息系统开发中,经常会用到各种各样的协议,网络协议常用的有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"] = 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字符串打印输出。

运行结果如下:

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/47915.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

使用 Webmin+bind9快速搭建私有DNS服务器

什么是DNS DNS是Domain name system的简称,有些地方也称为Domain name server DNS主要是用于将域名解析为IP地址的协议,有时候也用于将IP地址反向解析成域名,所以DNS可以实现双向解析。 DNS可以使用TCP和UDP的53端口,基本使用U…

HTML篇_二、HTML简介_HTML入门必修第一课

HTML篇_二、HTML简介 一、HTML的基本结构 1.1 HTML的基本结构及解析 基本结构 这里我们先放一段代码块来进行展示&#xff0c;感受一下来自HTML的魅力。然后下文再对这段代码块进行解析。 <!DOCTYPE html> <html><head><meta charset"utf-8&quo…

计算机组成原理习题课第三章-3(唐朔飞)

计算机组成原理习题课第三章-3&#xff08;唐朔飞&#xff09; ✨欢迎关注&#x1f5b1;点赞&#x1f380;收藏⭐留言✒ &#x1f52e;本文由京与旧铺原创&#xff0c;csdn首发&#xff01; &#x1f618;系列专栏&#xff1a;java学习 &#x1f4bb;首发时间&#xff1a;&…

JavaWeb

1、基础概念 静态web&#xff1a;html、css。给人看的数据始终不会发生改变。&#xff08;数据无法持久化&#xff0c;用户无法交互&#xff09; 动态web&#xff1a;①、淘宝、几乎所有网站&#xff1b; ②、给人看的数据始终会发生改变&#xff1b; ③、技术栈Servlet/JSP、…

可观测数据采集端的管控方案的简单对比

概述 当前&#xff0c;主流的日志采集产品除了SLS的ilogtail&#xff0c;还有Elastic Agent、Fluentd、Telegraf、Sysdig、Logkit、Loggie、Flume等。详细的对比结果见下表&#xff1a; 备注&#xff1a; 集群监控&#xff1a;表示工具可以查看管理采集端的运行状态、采集速…

iClient for MapboxGL对接WMS服务

作者&#xff1a;yx 文章目录前言一、获取WMS服务二、请求参数说明三、获取参数四、关键代码五、完整代码总结前言 咱们iClient官网Leaflet、OpenLayers、Classic均有对接WMS服务的示例&#xff0c;详情可以参考iClient官网示例https://iclient.supermap.io/。 但是许多小伙伴…

基础知识java

1.浅克隆和深克隆&#xff1f;深克隆的方法 浅克隆&#xff1a;对象的引用变量只会拷贝地址&#xff0c;不会新建一个对象 深克隆&#xff1a;对象的引用变量也会新建一个对象 实现方式&#xff1a; 浅克隆&#xff1a;实现cloneable接口的clone方法 深克隆&#xff1a;实现Ser…

《树莓派项目实战》第八节 使用光敏电阻传感器检测环境中是否有光照

目录 8.1 引脚介绍 8.2 工作原理 8.3 连接到树莓派 8.4 编写代码检测有无光照 在本节&#xff0c;我们将学习如何使用光敏电阻度传感器检测是否有光照&#xff0c;该项目设计到的材料有&#xff1a; 树莓派 * 1面包板 * 1杜邦线若干光敏电阻传感器 * 18.1 引脚介绍 从右到…

tictoc例子理解6-9

tictoc 6-9tictoc 6 自消息实现计时tictoc 7 节点等待时延随机&#xff0c;丢失包概率tictoc 8 两个节点分别定义两个类tictoc 9 保留原始包副本&#xff0c;从而不需要重新构建包tictoc 6 自消息实现计时 在前面的模型中&#xff0c;’ tic’和’ toc’立即将收到的消息发送回…

高防CDN和融合CDN的区别

所有网站比较关心的一个问题就是如何解决南北用户能够稳定的加速访问&#xff0c;为此网站运营商通常用的CDN来解决这个问题。那么CDN是什么呢&#xff1f;CDN是属于一种内容分发网络。通过在现有的网络中增加一层新的网络架构的模式&#xff0c;使用户能够就近获取数据&#x…

利用综合微生物指数评估富营养化危险沿海湿地生态状况

河海大学环境学院李轶课题组近期在《Science of the Total Environment》期刊上(IF10.753)发表的“Eutrophication dangers the ecological status of coastal wetlands: A quantitative assessment by composite microbial index of biotic integrity.”研究论文中&#xff0c…

IP-Guard批量部署客户端的方法有哪些?

常用的批量部署客户端方式有以下几种&#xff1a; 1、通过IP-guard域脚本安装工具推送安装 概括步骤如下&#xff1a; 1&#xff09;打包好客户端安装包&#xff08;勾选静默安装&#xff09;&#xff0c;将安装包命名为OAgentInst.exe 2&#xff09;将客户端安装包OAgentInst.…

React路由

文章目录单页面应用spa路由路由是什么React路由原理点击页面选项路径改变路径改变页面变化React路由的使用实现点击页面选项路径改变——编写路由链接根据路径显示组件 ——注册路由组件的分类——普通组件和路由组件案例实现选中高亮效果——NavLinkNavLink的封装Switch的使用…

tda4vm mcu1_0应用程序开发系列之ADC采样

文章目录 1. 前言2. 开发过程1. 前言 上一篇我们介绍了如何在tda4vm上拉起MCU域的mcu1_0,感兴趣的小伙伴可以看一下tda4vm如何SPL方式加载MCU域的核?,从本篇开始介绍如何在mcu1_0上开发应用程序,本篇主要介绍mcu1_0上ADC采样应用程序的开发。 2. 开发过程 如果工作中接到…

职业资格证书查询与验证

一、接口介绍 可查询多种类型的职业资格证书&#xff0c;包含&#xff1a;证券从业资格证查询、计算机信息高新技术考试证书查询、计算机技术与软件专业技术资格、全国教师资格证书查询、普通话证书查询合格证明、中小学教师资格考试合格证明&#xff08;NTCE&#xff09;、全国…

隐藏文件夹怎么显示,只需1分钟,快速学会

很多人在工作的过程中&#xff0c;将一些文件给隐藏了起来&#xff0c;后来需要使用的时候&#xff0c;却找不到隐藏的文件夹了。win10如何调出隐藏文件夹&#xff1f;隐藏文件夹怎么显示&#xff1f;只需1分钟&#xff0c;快速学会显示隐藏文件夹&#xff01; 隐藏文件夹怎么显…

【Mysql】复合查询

文章目录**1.基本查询回顾****2.多表查询** (重要)多表查询步骤**3.自连接**4.子查询在from子句中使用子查询5.合并查询1.基本查询回顾 准备工作,创建一个雇员信息表:&#xff08;来自oracle 9i的经典测试表&#xff09; EMP员工表 DEPT部门表 SALGRADE工资等级表 案例1:查询…

SVN+Gitee配置版本控制库

软件 TortoiseSVN&#xff1a;Downloads TortoiseSVN Gitee&#xff1a;https://gitee.com/ 操作步骤 在Gitee中新建仓库&#xff0c;设置仓库名以及模板&#xff08;Readme文件&#xff09;&#xff1b; 启用SVN访问 在仓库的管理页面&#xff0c;选择“功能设置”中的“…

为自己量身打造一个 Rust 项目模板/脚手架

摘要 quick-start-rs(quick start a rust project)是用于快速创建一个 rust 项目的脚手架/模板。 标题&#xff1a;为自己量身打造一个 Rust 项目模板/脚手架深度参考 Rust Code Quick Start文章来自 suhanyujieTags: Rust, utils, quick start, project template&#xff0c;脚…

视频编解码 — 带宽预测

目录 一、带宽预测作用 二、基于延时的带宽预测算法&#xff1a; 1、算法流程 2、计算延时 3、Trendline Filter 4、网络状态判断 5、带宽调整更新 三、基于丢包的带宽预测算法 1、带宽调整 四、最大带宽探测算法 五、最终的预测选择 一、带宽预测作用 控制音视频发…