一篇文章熟悉Python 开发Protobuf2(Google Protocol Buffers)

前言

Protobuf是google推出的一种数据协议,Protobuf(Google Protocol Buffers)。它具有高效的协议数据交换格式工具库(类似Json),它支持多语言(java、python、C++等等)、多平台(linux、win、mac等等)。

Protobuf简称proto,当前主要有proto2、proto3两个版本。本文主要介绍使用Python语言开发Protobuf2。

目录

前言

一、Protobuf特点

二、安装Protobuf

三、安装编译工具

四、定义 Protobuf、生成pb2.py文件、使用Protobuf

五、常用定义proto的语法

5.1 定义package

5.2 定义message

5.3 定义属性

花絮


一、Protobuf特点

  • 性能好/效率高: Protobuf传输效率快;相比于Json,Protobuf的时间效率和空间效率都比JSON强。
  • 格式扩展兼容:使用旧的proto协议编码仍然可以读取使用了新协议编码的数据,更新的新协议也可以兼容之前proto的定义。
  • 规范设计: Protobuf要求使用显式标识符和类型来规范消息。

 

二、安装Protobuf

使用pip安装Protobuf,执行如下命令即可:(简单方便,推荐)

pip install protobuf

查看版本:pip list | grep -i protobuf

 

三、安装编译工具

我们使用grpico-tools 软件包,生成服务器和客户端的接口代码,即生成 pb2.py 和 pb2_grpc.py 文件

pip install grpcio-tools

 

四、定义 Protobuf、生成pb2.py文件、使用Protobuf

1、我们首先定义一个 Protobuf,即:xxx.proto 文件,例如名为personal.proto

syntax = "proto2";

package tutorial;

message Person {
  required string name = 1;
  required int32 id = 2;
  optional string email = 3;
}
  • syntax = "proto2"; 是申明使用proto2版本。在.proto文件说明使用proto2还是proto3语法的声明:syntax = "proto2";,如果不声明默认使用proto2的语法。
  • package tutorial 为了避免不同项目的命名冲突,.proto文件以package xxxx;声明开头,作为协议唯一的标识。
  • message 是信息主体,类似一个结构体,里面能存放不同类型的数据;Person 是这个结构体的名称。比如:定义字符串——string,定义整型——int32,当然还有其他类型啦,后面再介绍。
  • required 是指使用这个结构体时一定需要的,需要给它赋值。optional 是可选的意思,可以选择用,也可以不用,不强制。在personal.proto 中需要给name、id 赋值,emailke可赋可不赋。

 

2、然后使用使用grpico-tools 生成pb2.py文件,即:生成personal_pb2.py文件

python -m grpc_tools.protoc -I ./ --python_out=./  personal.proto

备注:-I ./ 表示输入xxx.proto 文件所在的路经;./ 表示在当前目录。

--python_out=./ 表示输出的pb2.py文件放在那里;./ 表示在当前目录personal.proto 是要编译的文件名称。

 

3、最后我们使用Protobuf,即调用生成的personal_pb2.py文件

# -*- coding: utf-8 -*-

import personal_pb2

def run():
    data = personal_pb2.Person()
    data.name = 'guopu'
    data.id = 202103
    data.email = '12345678@qq.com'

    print(data)

if __name__ == '__main__':
    run()

运行结果:

.proto文件将编译后的以_pb.py结尾的文件,可以认为是普通的python脚本这样用的。

 

五、常用定义proto的语法

5.1 定义package

为了避免不同项目的命名冲突,.proto文件以package xxxx;声明开头,作为协议唯一的标识。

 

5.2 定义message

Message的嵌套使用可以嵌套定义,也可以采用先定义再使用的方式。

Message的定义末尾可以不加“;”,也可以末尾加上“;”这两种方式都兼容。

向.proto文件添加注释,可以使用双斜杠(//) 语法格式。

 

5.3 定义属性

属性定义分为四部分:标注+类型+属性名+属性顺序号+[默认值],其示意如下所示。

标注

类型

属性名

属性顺序号

[默认值]

required

string

name

= 1

[default=””];

 下面分别对标注、类型和属性顺序号加以详细介绍。

 

5.3.1 标注

标注包括“required”、“optional”、“repeated”三种,其中

required表示该属性为必选属性,否则对应的message“未初始化”,debug模式下导致断言,release模式下解析失败;

optional表示该属性为可选属性,不指定,使用默认值(int或者char数据类型默认为0,string默认为空,bool默认为false,嵌套message默认为构造,枚举则为第一个)

repeated表示该属性为重复字段,可看作是动态数组,类似于C++中的vector。

如果为optional属性,发送端没有包含该属性,则接收端在解析式采用默认值。对于默认值,如果已设置默认值,则采用默认值,如果未设置,则类型特定的默认值为使用,例如string的默认值为””。

 

5.3.2 类型

Protobuf的属性基本属性类型如下:

protobuf属性

Python属性

备注

double

double

固定8个字节

float

float

固定4个字节

int32

int32

使用变长编码,对于负数编码效率较低,如果经常使用负数,建议使用sint32

int64

int64

使用变长编码,对于负数编码效率较低,如果经常使用负数,建议使用sint64

uint32

uint32

使用变长编码

uint64

uint64

使用变长编码

sint32

int32

采用zigzag压缩,对负数编码效率比int32高

sint64

int64

采用zigzag压缩,对负数编码效率比int64高

fixed32

uint32

总是4字节,如果数据>2^28,编码效率高于unit32

fixed64

uint64

总是8字节,如果数据>2^56,编码效率高于unit32

sfixed32

int32

总是4字节

sfixed64

int64

总是8字节

bool

bool

 

string

string

一个字符串必须是utf-8编码或者7-bit的ascii编码的文本

bytes

string

可能包含任意顺序的字节数据

 

5.3.3 属性顺序号

属性顺序号是protobuf为了提高数据的压缩和可选性等功能定义的,需要按照顺序进行定义,且不允许有重复。

 

花絮

1)安装Protobuf,并查看版本

 

2)安装grpico-tools 编译工具

 

3)personal.proto 编译生成personal_pb2.py

personal_pb2.py的部分内容:

 

4)复杂版本的personal.proto

syntax = "proto2";
package tutorial;

message Person {
  required string name = 1;
  required int32 id = 2;
  optional string email = 3;

  enum PhoneType {
    MOBILE = 0;
    HOME = 1;
    WORK = 2;
  }

  message PhoneNumber {
    required string number = 1;
    optional PhoneType type = 2 [default = HOME];
  }

  repeated PhoneNumber phone = 4;
}

message AddressBook {
  repeated Person person = 1;
}

 

希望对你有帮助~

 

参考:Protobuf使用手册--中文版

 

 

 

 

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一颗小树x

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值