「ProtocolBuffers2」ProtocolBuffers2 Python简易入门

参考链接:
Protocol Buffer Basics: Python
Python Generated Code
Protocol Buffers Python API Reference

主要内容

  • 域的修饰符
  • 域中的数据类型
  • message方法
  • 定义一个.proto文件
  • 使用pb编译器
  • 使用pb读写消息

域(field)

域名 + {} = 一个完整的域,例如:

message 域名 {
     
  ...
}

message是标志符

域的修饰符

定义域时不需要修饰符,调用域类型(field type)时才需要

  • optional :可选类型。未设定则使用默认值;数值型默认为0,字符串默认空字符串,布尔默认true或false
  • repeated:可重复类型。可重复任意次数,每次产生的均会被存储,可看做一个动态变化的列表
  • required :要求类型。一般不使用。

域中的数据类型

  • bool
  • int32
  • float
  • double
  • string
  • 其他定义的域

message方法

  • IsInitialized():检查是否所有required域是否设定
  • __str__():输出人类可读的message,多用于debug。调用方式:str(message) / print message
  • CopyFrom(other_msg):重写message
  • Clear():清除所有信息至空状态

定义.proto文件

proto文件addressbook.proto内容定义如下:

syntax = "proto2";      //proto版本申明语句

package tutorial;       // package申明,防止不同项目中的同名冲突,不会对代码产生影响

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

  enum PhoneType {
            // 定义了一个enum类型,存储预设定的值
    MOBILE = 0;
    HOME = 1;
    WORK = 2;
  }

  message PhoneNumber {
     
    optional string number = 1;
    optional PhoneType type = 2 [default = HOME];  // 使用enum
  }

  repeated PhoneNumber phones = 4;
}

message AddressBook {
     
  repeated Person people = 1;
}

该文件定义了三个message数据结构,主message是AddressBook,其他message都是围绕该message展开;AddressBook带一个可重复的(repeated)Person结构(Person)的实例(people)。每个message是一个独立且隔离的域,因此在每个域中每个变量的编号是从1开始。
考虑到一个字节(byte,8bit)可以表示0-15十六个数和计算机存储的空间局部性,推荐将经常使用的变量编码为较小的值以提高效率。

编译proto文件

  1. 编译前要先安装编译器:Download Protocol Buffers

  2. 编译命令:

    protoc  -I=/proto/file/folder/path  --python_out=/compiled/saving/path  /proto/file/path
    

    编译xxx.proto文件后生成proto_pb2.py文件,直接在python导入生成的py文件即可

    python protocol buffer编译器并不直接生成获取数据的代码,而是生成一个特殊的描述器来描述.proto中定义的所有数据结构:

    class Person(message.Message):
      __metaclass__ = reflection.GeneratedProtocolMessageType # 重要代码
    
      class PhoneNumber(message.Message):
        __metaclass__ = reflection.GeneratedProtocolMessageType
        DESCRIPTOR = _PERSON_PHONENUMBER
      DESCRIPTOR = _PERSON
    
    class AddressBook(message.Message):
      __metaclass__ = reflection.GeneratedProtocolMessageType
      DESCRIPTOR = _ADDRESSBOOK
    

    可以将这些代码看做一个创建类的模板,在加载时,通过GeneratedProtocolMessageType元类来调用特殊描述器来创建所有proto定义内容的python方法。

写message

import addressbook_pb2                                       # 导入编译好的py文件

person_1 = addressbook_pb2.Person()            # 申请一个Person实例
person_1.id = 123                                                       # 赋值
person_1.name = "Dady"
person_1.email = "[email protected]"

phone_1 = person.phones.add()                          # 对于repeated类数据,使用add()来新增实例
phone_2 = person.phones.add() 
phone_1.number = "123-456-789"
phone.type = addressbook_pb2.Person.Home

读message

在接收到一个message后,直接调用即可

import addressbook_pb2                     

# 假定接收到了一个address_book message,且address_book包含多个人

for person in address_book.people:
	person_id = person.id
	person_name = person.name
	print(person_id, person_name)

你可能感兴趣的:(ProtocolBuffer,python)