工作经常使用proto,但只是简单了解,没有深入学习,现梳理如下
1. protobuf 介绍
参见
- https://developers.google.com/protocol-buffers/
- https://www.ibm.com/developerworks/cn/linux/l-cn-gpb/
Google Protocol Buffer( 简称 Protobuf) 是 Google 公司内部的混合语言数据标准,它是
一种轻便高效的结构化数据存储格式
,可以用于结构化数据串行化,或者说序列化。它很适合做数据存储或 RPC 数据交换格式
。可用于通讯协议、数据存储等领域的语言无关、平台无关、可扩展的序列化结构数据格式。支持 c#, dart, Go, java,python语言.
2. protobuf 安装
-
直接从github下载[https://github.com/protocolbuffers/protobuf] (https://github.com/protocolbuffers/protobuf) zip包
-
解压进入目录,执行命令 ./configure --prefix=
$你的path
-
依次执行命令make、make check、make install
-
该目录下产生bin文件夹,安装成功
-
设置环境变量vim ~/.bash_profile
export PATH=$PATH:/home/work/tool/protobuf/protobuf-2.6.1/binexport LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/work/tool/
protobuf/protobuf-2.6.1/libsource ~/.bash_profile
当为Python使用时,需要执行一下操作:
-
以下为python使用安装
cd ./python
python setup.py install
3. protobuf 简单使用
(1) 举例:info_person.proto
package Info;
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;
}
- 其中
required
:必要型。表示该值是必须要设置的 -
optional
:选择型。消息格式中该字段可以有0个或1个值(不超过1个) -
repeated
:重复型。在一个格式良好的消息中,这种字段可以重复任意多次 -
enum
: 枚举型。当需要定义一个消息类型的时候,可能想为一个字段指定某“预定义值序列”中的一个值。
认真对待 proto 文件的文件名。比如将命名规则定于如下:
packageName_MessageName.proto
(2) 使用编译.proto文件,
使用protoc -I=./ --python_out=./ info_person.proto
进行编译。本例中生成info_person_pb2.py
说明
a.-I
是原文件路径,
b.--python_out
表示对应python库的生成路径,
c. info_person.proto 是指定编译的proto文件
(3) 如何使用pb2文件
#-*- coding: utf-8 -*-
import os
import info_person_pb2 # 导入生成的pb文件
if __name__ == '__main__':
person = info_person_pb2.Person()
person.name = 'xiaozhang'
person.id = 1
person.email = 'hello@xx.email.com'
# 嵌套message
phone_number = person.phone.add()
phone_number.number = '1234567'
phone_number.type = 0
print "====序列化===="
phone_serialize = phone_number.SerializeToString()
person_serialize = person.SerializeToString()
print type(person_serialize)
print person_serialize # 二进制字符串,不可读
print "====反序列化===="
person2 = info_person_pb2.Person()
person2.ParseFromString(person_serialize)
print type(person2)
print person2
print "====获取required字段===="
print person2.name
print "====获取嵌套message信息===="
for aphone in person2.phone:
print aphone.number
测试结果:
网友评论