前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Python Protobuf入门

Python Protobuf入门

原创
作者头像
千万别过来
修改2023-08-11 18:59:44
1.4K0
修改2023-08-11 18:59:44
举报
文章被收录于专栏:推荐算法学习推荐算法学习

最近在做模型的时候发现工程实时落盘的样本是Protobuf序列化后的数据,为了读取这些数据,简单的了解了一下Protobuf。

Protocol Buffers(简称 Protobuf)是一种轻便高效的结构化数据存储格式,可用于结构化数据串行化,很适合进行数据存储和通信协议这样的轻量级应用。类似的还有JSON、XML等。Protobuf独立于语言、平台,同时也易于阅读和理解。这里将以一个例子介绍如何在Python中使用Protobuf。

1.安装protobuf

首先,需要安装了protobuf库。通过以下命令安装:

代码语言:javascript
复制
pip install protobuf

2.编写proto文件

接下来,需要定义一个.proto文件,描述我们要序列化的数据结构。例如,创建一个名为person.proto的文件,内容如下:

代码语言:javascript
复制
syntax = "proto3";
message Person {
  string name = 1;
  int32 age = 2;
  string email = 3;
}

proto3是protobuf的版本。在这个例子中,定义了一个名为Person的消息,它有三个字段:nameageemail

当然这里在编写proto文件的时候也有一些小工具来提高我们的效率,比如json转proto:

https://json-to-proto.github.io/

3.根据proto文件生成python文件

接下来,我们需要编译这个.proto文件,生成对应的Python代码(c++、java、go也有类似的):

代码语言:javascript
复制
protoc --python_out=. person.proto

这将自动生成一个名为person_pb2.py的Python文件,其中包含定义的数据结构和序列化/反序列化代码。看一下注释,这个代码不需要编辑(DO NOT EDIT!),直接扔到后面需要使用的地方就行了。

注意:这里的pb2并不代表proto2pb2是protobuf编译器(protoc)生成的Python文件的默认命名规则。与protobuf的版本无关。

4.使用protobuf

现在我们可以开始在Python中使用protobuf了。以下是一个简单的示例:

代码语言:javascript
复制
import person_pb2

# 创建一个Person对象并设置字段值
person = person_pb2.Person()
person.name = "张三"
person.age = 30
person.email = "zhangsan@example.com"

# 序列化Person对象为二进制字符串
serialized_person = person.SerializeToString()
print(f"序列化后的数据:{serialized_person}")

# 反序列化二进制字符串为一个新的Person对象
new_person = person_pb2.Person()
new_person.ParseFromString(serialized_person)

# 输出新的Person对象的字段值
print(f"反序列化后的数据:姓名={new_person.name}, 年龄={new_person.age}, 邮箱={new_person.email}")

运行结果:

注意:需要导入了person_pb2模块(上一步生成的python文件)

5.常用API

建议直接看官方API:https://protobuf.dev/reference/

下面也列举了一些常用的API,其中protobuf_data为python生成的对象。比如person = person_pb2.Person()里面的person

API

描述

示例

SerializeToString()

将 Protobuf 对象序列化为二进制字符串

serialized_data = protobuf_data.SerializeToString()

ParseFromString(data)

将二进制字符串反序列化为 Protobuf 对象

protobuf_data.ParseFromString(serialized_data)

MergeFromString(data)

将二进制字符串合并到现有的 Protobuf 对象

protobuf_data.MergeFromString(serialized_data)

SerializePartialToString()

将 Protobuf 对象序列化为二进制字符串,即使某些必需字段未设置

serialized_data = protobuf_data.SerializePartialToString()

IsInitialized()

检查 Protobuf 对象的所有必需字段是否已设置

protobuf_data.IsInitialized()

ListFields()

返回一个包含 Protobuf 对象已设置字段的List

fields = protobuf_data.ListFields()

Clear()

清除 Protobuf 对象的所有字段值,将其重置为初始状态

protobuf_data.Clear()

ClearField(field_name)

删除 Protobuf 对象中指定字段的值

protobuf_data.ClearField("field_name")

HasField(field_name)

检查 Protobuf 对象中的指定字段是否已设置

protobuf_data.HasField("field_name")

6.写pb文件

在上面的基础上,将 Protobuf 对象序列化为二进制字符串可以保存至pb文件,方法很简单,和写文本文档的方法一样:

代码语言:javascript
复制
with open('test.pb', 'wb') as fb:
    fb.write(serialized_person)

其中serialized_person为上面序列化为二进制字符串。这样保存下来的文件大概是这样:

但是Protobuf 序列化后的数据是二进制格式,通常无法直接以文本形式展示(或者看起来很奇怪)。因此将二进制数据转换为 Base64 编码的字符串是一种常见的做法, Base64 编码后的字符串可以在文本协议(如电子邮件、JSON、XML等)中传输和存储。因此以上代码修改为:

代码语言:javascript
复制
import base64

with open('test.pb', 'wb') as fb:
    fb.write(base64.b64encode(serialized_person))

这样保存的就是Base64编码后的结果了。(使用的时候注意需要先用Base64解码)

参考:

https://protobuf.dev/getting-started/pythontutorial/

https://www.cnblogs.com/autyinjing/p/6495103.html

https://cloud.tencent.com/developer/article/2182255

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1.安装protobuf
  • 2.编写proto文件
  • 3.根据proto文件生成python文件
  • 4.使用protobuf
  • 5.常用API
  • 6.写pb文件
相关产品与服务
数据保险箱
数据保险箱(Cloud Data Coffer Service,CDCS)为您提供更高安全系数的企业核心数据存储服务。您可以通过自定义过期天数的方法删除数据,避免误删带来的损害,还可以将数据跨地域存储,防止一些不可抗因素导致的数据丢失。数据保险箱支持通过控制台、API 等多样化方式快速简单接入,实现海量数据的存储管理。您可以使用数据保险箱对文件数据进行上传、下载,最终实现数据的安全存储和提取。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档