protbuf极简入门例子
Google官方的tutorial废话有点多, 而且例子也有点不直观. 自己在官方例子上简化修改了一个极简版的, 足够知道Python下主要的用法了. 其实这就是一个序列化对象协议的东西.
步骤
-
下载protoc-3.11.4-win64 (https://github.com/protocolbuffers/protobuf/releases/tag/v3.11.4页面里面找protoc-3.11.4-win64.zip). 这个zip包里面包含bin/protoc.exe, c代表compiler, 因此这个就是负责编协议的exe执行程序. 把这个文件夹的路径添加的系统的PATH里面(比如D:\Downloads\protoc-3.11.4-win64\bin).
-
新建一个如下的proto文件myperson.proto
-
首先编译一下proto文件, 相当于编协议. 切换到myperson.proto所在目录, 本地cmd执行
protoc --python_out=./ myperson.proto
注意这里的--python_out必不可少, 因为protoc.exe需要知道是编出哪个语言的代码. 此处可以用./
表示在本目录. -
然后本地执行
python my_add_person.py
执行一下, 然后python my_list_person.py
执行一下看看结果
说明: 这个例子是在官方的例子上简化修改而成的, 更适合中文下快速入门.
后续: 去研究一下python代码里面的过程, 看一下官方文档, 就差不多懂得protobuf的机制了.
案例代码
myperson.proto 制定协议
// [START declaration]
syntax = "proto3";
package tutorial;
import "google/protobuf/timestamp.proto";
// [END declaration]
// 定义一个message类型 Person, 非常类似Java定义一个类
// 可以使用的字段类型有:
// int, string, enum,
// 或者是自定义的PhoneNumber类型(等于一个dict), 或者是repeated(等价一个list)
message Person {
string name = 1;
int32 id = 2; // Unique ID number for this person.
string email = 3;
enum PhoneType { // 枚举类型
MOBILE = 0;
HOME = 1;
WORK = 2;
}
message PhoneNumber { // 一个message类型的内部可以定义一个本地作用域内的类型, 使用起来类似一个dict
string number = 1;
PhoneType type = 2;
}
repeated PhoneNumber phones = 4; // repeated意思说可以有n个, 用起来比较类似一个list
google.protobuf.Timestamp last_updated = 5; // 用一下时间戳字段标记上次更新时间
}
// 定义一个AddressBook类型, 它的成员字段是可以重复的Person(相当于有n个person)
message AddressBook {
repeated Person person_list = 1;
}
my_add_person.py
# coding:utf-8
import myperson_pb2
import sys
address_book = myperson_pb2.AddressBook()
file_path = "./myaddressbook.data"
# Read the existing address book.
try:
with open(file_path, "rb") as f:
address_book.ParseFromString(f.read())
except IOError:
print(file_path + ": File not found. Creating a new file.")
# 给对象的各个字段赋值
person = address_book.person_list.add() # 给address_book.person_list添加一个新的person对象
person.id = 1002
person.name = "Bob"
person.email = "bob@example.com"
phone = person.phones.add() # 相当于list添加一个新的成员phone
phone.number = "666555"
phone.type = 1;
# Write the new address book back to disk.
with open(file_path, "wb") as f:
f.write(address_book.SerializeToString()) # 把整个address_book对象序列化为字符串, 准备存储或者网络传输
print("code end")
my_list_person.py
# coding:utf-8
from __future__ import print_function
import myperson_pb2
import sys
# Iterates though all people in the AddressBook and prints info about them.
def ListPeople(address_book):
for person in address_book.person_list:
print("Person ID:", person.id)
print(" Name:", person.name)
if person.email != "":
print(" E-mail address:", person.email)
for phone_number in person.phones:
if phone_number.type == myperson_pb2.Person.MOBILE:
print(" Mobile phone #:", end=" ")
elif phone_number.type == myperson_pb2.Person.HOME:
print(" Home phone #:", end=" ")
elif phone_number.type == myperson_pb2.Person.WORK:
print(" Work phone #:", end=" ")
print(phone_number.number)
address_book = myperson_pb2.AddressBook()
file_path = "./myaddressbook.data"
# Read the existing address book.
with open(file_path, "rb") as f:
address_book.ParseFromString(f.read())
ListPeople(address_book)
网友评论