基于google protobuf的gRPC实现(python版)

1.Protobuf简介

** Protobuf(Google Protocol Buffers) ** 提供一种灵活、高效、自动化的机制,用于序列化结构数据。Protobuf仅需自定义一次所需要的数据格式,然后我们就可以使用Protobuf编译器自动生成各种语言的源码,方便我们读写自定义的格式化数据。另外Protobuf的使用与平台和语言无关,可以在不破坏原数据格式的基础上,扩展新的数据。

我们可以将Protobuf与XML进行对比,但Protobuf更小、更快、更加简单。总结来说具有一下特点

  • 性能好、效率高。Protobuf作用与XML、json类似,但它是二进制格式,所以性能更好。但同时因为是二进制格式,所以缺点也就是可读性差。
  • 代码生成机制,易于使用。
  • 解析速度快。
  • 支持多种语言,例C++、C#、Go、Java、Python等。
  • 向前兼容,向后兼容。

2.Protobuf安装

Mac用户可以使用brew进行安装,命令如下所示。

brew install protobuf

如需要安装特定版本,可以先进行搜索有哪些版本,命令如下所示。搜索完成之后,采用上述brew安装方法,安装特定版本即可。

brew search protobuf

安装完成之后,可以通过protoc --version查看是否安装成功。

protoc --version
libprotoc 3.6.0

另外可以通过which protoc命令查看protoc安装所在的位置。

which protoc
/usr/local/bin/protoc

3.Protobuf实例

3.1编译.proto文件

首先我们需要创建一个以**.proto结尾的文件,可以在其中定义message**来指定所需要序列化的数据格式。每一个message都是一个小的信息逻辑单元,包含一系列的name-value值对。以官网上示例,我们创建一个addressbook.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 phones = 4;
}

message AddressBook {
   
  repeated Person people = 1;
}
  • **syntax=”proto2”**代表版本,目前支持proto2和proto3,不写默认proto2。
  • package类似于C++中的namespace概念。
  • message是包含了各种类型字段的聚集,相当于struct,并且可以嵌套。
  • proto3版本去掉了required和optional类型,保留了repeated(数组)。其中“=1”,“=2”表示每个元素的标识号,它会用在二进制编码中对域的标识,[1,15]之内的标志符在使用时占用一个字节,[16,2047]之内的标识号则占用2个字节,所以从最优化角度考虑,可以将[1,15]使用在一些较常用或repeated的元素上。同时为了考虑将来可能会增加新的标志符,我们要事先预留一些标志符。

构建好addressbook.proto文件后,运行Protobuf编译器编译.proto文件,运行方法如下所示。其中-I表示.protoc所在的路径,--python_out表示指定生成的目标文件存在的路径,最后的参数表示要编译的.proto文件。

protoc -I=$SRC_DIR --python_out=$DST_DIR $SRC_DIR/addressbook.proto

其中SRC_DIR为目录,如果处于当前目录的话,可通过如下所示命令来编译.proto文件。

protoc -I=. --python_out=. addressbook.proto

编译完成之后会生成addressbook_pb2.py文件,里面包含序列化和反序列化等方法。

3.2序列化

import addressbook_pb2
import sys

def PromptForAddress(person):
  person.id = int(raw_input("Enter person ID number: "))
  person.name = raw_input("Enter name: ")

  email = raw_input("Enter email address (blank for none): ")
  if email != "":
    person.email = email

  while True:
    number = raw_input("Ente
  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值