Protobuf协议初级详解(python使用)从安装到序列化-反序列化

news2024/11/26 16:27:52

教程

  • 一、前言
  • 二、效果
  • 三、教程
    • 1)安装
    • 2)使用
      • 1.创建.proto文件
      • 2.proto语法
      • 3.protoc.exe文件编译.proto语法文件
      • 4.序列化
      • 5.反序列化
  • 四、借鉴

一、前言

  • Protobuf是一种轻便高效的结构化数据存储格式,可以用于结构化数据序列化,很适合做数据存储或 RPC 数据交换格式。它可用于通讯协议、数据存储等领域的语言无关、平台无关、可扩展的序列化结构数据格式。

  • 可以简单理解为,是一种跨语言、跨平台的数据传输格式。与json的功能类似,但是无论是性能,还是数据大小都比json要好很多。

  • protobuf的之所以可以跨语言,就是因为数据定义的格式为.proto格式,需要基于protoc编译为对应的语言。

二、效果

既然说到了性能,还是数据大小都比json要好很多。那么我们不如来用一个例子了解一下具体展现在哪里。这同一个数据经过Protobuf和Json格式转换后的数据大小。可以直观的看到Protobuf足足少了四分之三。
在这里插入图片描述

三、教程

1)安装

protobuf下载地址
我是windows所以就选择了windows的包
在这里插入图片描述
将protoc-23.1-win64.zip解压后打开该目录的bin目录,复制路径
在这里插入图片描述
打开电脑的环境变量设置,在系统变量下面选择Path变量编辑在这里插入图片描述
新建一个,然后将复制的路径粘贴到下面
在这里插入图片描述
在命令行敲一下下面命令查看是否可以正常调用

protoc --version

在这里插入图片描述
然后再解压protobuf-23.1.zip文件,找到python
在这里插入图片描述

)
python目录打开cmd将下面三条命令敲入(pip的protobuf和下载的protobuf版本最好一致)–要在当前目录下的cmd噢

pip install protobuf
python setup.py build
python setup.py install

在这里插入图片描述
cmd打开python可以正常输入下面命令就代表安装成功了。

from google.protobuf.internal import builder

在这里插入图片描述

2)使用

一个大概流程图
在这里插入图片描述

1.创建.proto文件

根据流程图,我们第一步是创建一个.proto文件
在这里插入图片描述

2.proto语法

既然知道这是一个语法文件,那么里面肯定是要写一些语法在里面的。
这些语法是相当于一个和使用者的约定,约定这些字段是这种语法定义的结构。(这里只是基础例子写的语法,具体的可以看文章gRPC之proto语法)

//第一行的含义是使用的是proto3的语法,如果没有这句,则默认使用proto2;
syntax = "proto3";
/*Person定义有三个承载消息的属性,每一个被定义在Person 消息体中的字段,都是由数据类型和属性名称组成。
里面的123是代表了编号,protobuf为了节省空间,使用了编号来代替字段名,只有服务器和客户端拥有同样的proto语法文件才可以知道正确的字段名
不然解析出来的也是123为代表的结果
 */
message Person {
    int32 id = 1;
    string name = 2;
    message Iphone {
        string number = 1;
    }
    //repeated: 这个属性代表了可以重复增加,就相当于往List数组增加数据
    repeated Iphone phones = 3;
}

message totalPerson{
    repeated Person person = 1;
}

3.protoc.exe文件编译.proto语法文件

在cmd输入下面命令,example.proto是你写的.proto语法文件。

protoc --python_out=. example.proto

在这里插入图片描述
然后会在同级目录下出现example_pb2.py文件
在这里插入图片描述

4.序列化

既然得到了example_pb2.py文件,那我们可以开始尝试序列化一份数据了。
先创建一份main.py文件,通过定义好的example_pb2.py文件语法来定义数据(实则是根据.proto文件来定义),然后进行一个序列化操作(使用SerializeToString)。

import example_pb2

# 从生成的example_pb2导入totalPerson(相当于初始化对象)
result_pro = example_pb2.totalPerson()
# 从语法文件可以看到totalPerson中有repeated就代表person是可以被add多个的,我们这里就新增一个就好了;
person_message = result_pro.person.add()
# person被初始化后,就可以定义里面的属性了
person_message.id = 1
person_message.name = "laowang"
# 基础属性定义完后,还有一个复合属性phones,这里对他进行一个新增初始化
phone = person_message.phones.add()
# 定义对象属性
phone.number="123456"

# 这里是将定义好的数据进行一个序列化操作
result=result_pro.SerializeToString()
print(result)
print("Protobuf: ", result.__sizeof__())

# 这里是将定义好的数据进行一个序列化操作并且存入到bin文件
with open("my_example.bin", "wb") as f:
	f.write(result)

在这里插入图片描述

5.反序列化

上图可以看到成功序列化数据出来了,我们现在则要对保存的bin文件进行反序列化

  • 先通过有proto语法文件的反序列化(使用ParseFromString)
import example_pb2

# 从生成的example_pb2导入totalPerson(相当于初始化对象)
result_pro = example_pb2.totalPerson()

with open("my_example.bin", "rb") as f:
	result_pro.ParseFromString(f.read())
	print(result_pro)

在这里插入图片描述
可以看到很好的还原出来了我们定义并且想要的数据格式。接下来我们看看json类似的数据格式与之对比
在这里插入图片描述

  • 无proto语法文件的反序列化
    如果没有语法文件呢,不用急,protobuf给了我们这样一个工具可以帮助我们除了键名基本还原出来。(在my_example.bin同级目录下打开cmd输入下面命令)
protoc --decode_raw < my_example.bin

可以得到下面的数据结构,对比上面除了键名不同其他都是一样的,这就是protobuf对于键名不是很敏感的原因,他更敏感我们上面注释说的编号。这里展现的就是我们之前给键名定义的编号。
所以如果想要复刻只需要自己重新写一个proto语法文件,对照着编号结构,重新起一个键名进行生成_pb2.py文件去达到序列化相同的数据结构。
在这里插入图片描述
新建一个myprotobuf.proto语法文件,把键名全部换了(图方便相当于根据上图的结果来模拟一个.proto语法结构)

syntax = "proto3";

message newPerson {
    int32 newid = 1;
    string newname = 2;
    message newIphone {
        string newnumber = 1;
    }
    repeated newIphone newphones = 3;
}

message newtotalPerson{
    repeated newPerson newperson = 1;
}

然后编译它生成myprotobuf_pb2.py

protoc --python_out=. myprotobuf.proto

修改main.py文件调用,这里还是读取我们上次序列化数据的bin文件

import myprotobuf_pb2

# 从生成的example_pb2导入totalPerson(相当于初始化对象)
result_pro = myprotobuf_pb2.newtotalPerson()
# 反序列化
with open("my_example.bin", "rb") as f:
    result_pro.ParseFromString(f.read())
    print(result_pro)

可以看到成功反序列化出来了数据
在这里插入图片描述

四、借鉴

什么是protobuf
gRPC之proto语法
JS逆向-Protobuf逆向解析

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

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

相关文章

chatgpt赋能python:Python随机抽取:提高数据样本代表性的利器

Python随机抽取&#xff1a;提高数据样本代表性的利器 在数据分析和机器学习领域&#xff0c;我们经常需要对数据进行随机抽样以获得更有代表性的数据集。而Python提供了很多方便易用的函数和库&#xff0c;使得数据抽样变得更加简单和高效。 random库&#xff1a;生成随机序…

chatgpt赋能python:Python随机选择数字

Python随机选择数字 如果你正在寻找一种简单的方法在Python中选择随机数字&#xff0c;那么你来对地方了&#xff01;在这篇文章里&#xff0c;我们将介绍Python的内置模块random和它的方法来选择随机数字。 什么是Python的Random模块&#xff1f; Python的random模块是一个…

chatgpt赋能python:Python中的随机选择:介绍和应用

Python中的随机选择&#xff1a;介绍和应用 Python是一种流行的编程语言&#xff0c;广泛应用于数据科学、人工智能和网络开发等领域。Python中有许多方便的功能和库&#xff0c;使得编程工作更加轻松和高效。其中一个重要的库是random模块&#xff0c;它可以用来生成随机数和…

横向移动-传递攻击SMB服务利用psexecsmbexec

win2012以上版本&#xff0c;关闭了wdigest 或者安装了 KB287199补丁。无法获取明文密码 总的来说就是win2012后无法获取明文密码 解决办法就是&#xff1a; 1.可以利用哈希hash传递&#xff08;pth&#xff0c;ptk等进行移动&#xff09; 2.利用其他服务协议&#xff08;S…

chatgpt赋能python:【Python实例教程】如何使用Python计算长方形面积

【Python实例教程】如何使用Python计算长方形面积 Python是一种广泛使用的高级编程语言&#xff0c;因其易学易用的特性而备受推崇。Python在编写程序时也可以很方便地进行数学计算。本篇文章将介绍如何使用Python计算长方形的面积&#xff0c;希望对Python初学者有所帮助。 …

访客管理系统:Lobby Track Crack

Lobbytrack桌面 for 微软视窗 一个强大的、功能齐全的现场访客管理系统解决方案。在本地管理您的数据&#xff0c;网络工作站一起配置访客管理流程的各个方面。 扩展您的系统将本地 Web 模块 添加到您的 Lobbytrack 桌面系统&#xff0c;并允许您的员工使用本地 Intranet 上的 …

【Cookie和Session】

&#x1f389;&#x1f389;&#x1f389;点进来你就是我的人了博主主页&#xff1a;&#x1f648;&#x1f648;&#x1f648;戳一戳,欢迎大佬指点! 欢迎志同道合的朋友一起加油喔&#x1f93a;&#x1f93a;&#x1f93a; 目录 一、Cookie和Session&#xff08;面试常考&…

目标检测YOLO实战应用案例100讲-基于深度学习的无人机航拍图像目标检测算法研究与应用

基于深度学习的无人机航拍图像目标检测算法研究与应用 无人机是无线遥控装置和内置的程序控制装置操纵,亦或由车载计算机完全地 或间歇地规律操控的不载人飞机。无人机的地面航拍成像在军事探察、地质勘探、 公安侦查等领域[1-2]得到广泛应用。在军事领域,能够通过无人机进行…

chatgpt赋能Python-python_读取png

前言 Python是一种高级编程语言&#xff0c;尤为擅长处理数据科学和机器学习方面的应用。PNG&#xff08;Portable Network Graphics&#xff09;是一种流行的图像格式&#xff0c;它使用无损压缩技术来存储图像数据。在本文中&#xff0c;我们将介绍如何使用Python读取PNG图像…

SAP MM采购申请审批-成本中心

抬头审批的采购申请中行项目里的成本中心必须是同一个! 1、创建特性成本中心CT04 2、把特性分配给类CL02 3、维护分类审批策略 这些成本中心都可以使用&#xff0c;如果是单项就需要再CT04维护成多值。 如下采购申请&#xff0c;系统找不到审批策略, 2个行项目中&#xff0c;成…

【C语言】简单排序:冒泡排序和选择排序(含图解)

文章目录 1. 冒泡排序1.1 思想1.2 代码实现 2. 选择排序2.1 思想2.2 代码实现 1. 冒泡排序 1.1 思想 选择排序算法思想&#xff1a;以升序为例 比较相邻的元素。如果第一个比第二个大&#xff0c;就交换他们两个。对每一对相邻元素作同样的工作&#xff0c;从开始第一对到结…

了解list

list 1. list的介绍及使用1.1 list的介绍1.2 list的使用1.2.1 list的构造1.2.2 list iterator的使用1.2.3 list capacity1.2.4 list element access1.2.5 list modifiers1. resize2. push_back/pop_back/push_front/pop_front3. insert /erase4. swap/clear 1.2.6 list operati…

chatgpt赋能python:Python中的数字转换

Python中的数字转换 在Python中&#xff0c;数字转换是一项非常基础但是非常重要的任务。无论您是在进行数据分析、机器学习还是编写Web应用程序&#xff0c;数字转换都是必不可少的。在这篇文章中&#xff0c;我们将介绍Python中的数字转换并提供一些实用的示例。 将字符串转…

Unity之SpriteShapeController

Detail&#xff1a;精灵形状的质量 高中低三种质量 Is Open Ended&#xff1a;是否是开放的&#xff0c;不封闭的 Adaptive UV&#xff1a;自适应UV&#xff0c;如果开启&#xff0c;会自动帮助我们判断是平铺还是拉伸 开启后只有宽度够才会平铺&#xff0c;如果宽度不够会拉…

micropython固件编译——把自己的py库添加进固件

目录 0. 前言1. 编写自己库的代码2. 移植库3. 验证 0. 前言 本节编译自己写的py库&#xff0c;增强移植性&#xff0c;往后烧录自己的固件即可轻易移植代码 没装好环境或者没有基础可以先看看这个&#xff1a; Ubuntu下ESP-IDF的环境搭建 Ubuntu下编译esp32micropython固件编…

antV 事件多次触发问题,解绑

由于最近刚刚接触 antV - 数据可视化,对于他的事件应用还比较陌生,在应用中莫名其妙多次调用,想了很多方式如节流……,但是没有用。 业务介绍 当我点击流程图中的某一项进行提示,每次双击都会递增调用。 解决过程 当时想着用节流的方式,但是很遗憾,他还是疯狂递增调用…

Go语言的命令

常用命令 假如你已安装了golang环境&#xff0c;你可以在命令行执行go命令查看相关的Go语言命令&#xff1a; Go语言是一门编译型语言&#xff0c;通过命令行工具来编译、运行和管理代码。以下是Go语言的一些常用命令及其用法&#xff1a; go run&#xff1a;用于编译并直接…

chatgpt赋能python:Python补全:介绍和优点

Python补全&#xff1a;介绍和优点 Python是一种高级编程语言&#xff0c;自20世纪90年代以来一直广受欢迎。Python被认为是一种非常易学易用的语言&#xff0c;因为它的代码看起来就像是英文一样流畅自然。它是一种解释性语言&#xff0c;这意味着代码可以直接在计算机上运行…

LeetCode 24. 两两交换链表中的节点

C代码&#xff1a; class Solution { public:ListNode* swapPairs(ListNode* head) {ListNode* dummyHead new ListNode(0);//设置一个虚拟头结点dummyHead->next head;// 将虚拟头结点指向head&#xff0c;这样方面后面做删除操作ListNode* cur dummyHead;//初始时&…

Android SharedPreferences转为MMKV

开篇 开局一张图&#xff0c;说明一切问题。 MMKV优势 可以看出MMKV相比SP的优势还是比较大的&#xff0c;除了需要引入库&#xff0c;有一些修改上的成本以外&#xff0c;就没有什么能够阻挡MMKV了。当然了&#xff0c;MMKV也有着不广为人知的缺点&#xff0c;放在最后。 MM…