这篇文章主要介绍了如何在mac环境中用python处理protobuf,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
安装
brew install protobuf
然后再安装protobuf需要的依赖
brew install autoconf automake libtool
验证是否安装成功
protoc –version
protobuf3语法介绍
1.字段前取消了required和optional两个关键字,目前可用的只有repeated关键字。
2.不可以现设置默认值了。
a.string默认为空串
b.枚举默认为第一个枚举定义的第一个值。并且必须是0,必须有有一个0值,我们可以用这个0值作为默认值。
这个零值必须为第一个元素,为了兼容proto2语义,枚举类的第一个值总是默认值。
c.bytes默认为空bytes
d.bool默认为false
e.数字类型默认为0
3.protoType类型如下:
double、float、int32、int64、uint32、uint64、sint32、sint64、fixed32、fixed64、sfixed32、sfixed64、bool、string、bytes
4、分配标识号
正如你所见,在消息定义中,每个字段都有唯一的一个数字标识符。这些标识符是用来在消息的二进制格式中识别各个字段的,一旦开始使用就不能够再改变。注:[1,15]之内的标识号在编码的时候会占用一个字节。[16,2047]之内的标识号则占用2个字节。所以应该为那些频繁出现的消息元素保留 [1,15]之内的标识号。切记:要为将来有可能添加的、频繁出现的标识号预留一些标识号。
最小的标识号可以从1开始,最大到2^29 - 1, or 536,870,911。不可以使用其中的[19000-19999]( (从FieldDescriptor::kFirstReservedNumber 到 FieldDescriptor::kLastReservedNumber))的标识号, Protobuf协议实现中对这些进行了预留。如果非要在.proto文件中使用这些预留标识号,编译时就会报警。同样你也不能使用早期保留的标识号。
指定字段规则
所指定的消息字段修饰符必须是如下之一:
在proto3中,repeated的标量域默认情况虾使用packed。
编写protoco文件,addressbook.proto。
syntax = "proto3"; //正在使用proto3语法,如果你没有指定这个,编译器会使用proto2 package tutorial; //*.proto文件中数据类型可以分为两大类: //复合数据类型包括:枚举和message类型 //标准数据类型包含:整型,浮点,字符串等 message AddressBook { //repeated: 该字段可以重复任意次数,包括0次。重复数据的顺序将会保存在protocol buffer中,将这个字段想象成一个可以自动设置size的数组就可以了。 repeated Person people = 1; } message Person { //每个字段有一种类型 //该Number是用来标记该字段在序列化后的二进制数据中所在的field, //每个字段的Number在message内部都是独一无二的。也不能进行改变,否则数据就不能正确的解包 string name = 1; int32 id = 2; string email = 3; float money =4; bool work_status = 5; repeated PhoneNumber phones =6; MyMessage maps =7; } message PhoneNumber{ string number =1; PhoneType type =2; } enum PhoneType{ MOBILE =0; HOME =1; WORK =2; } message MyMessage{ mapmapfield =1; }
编译生成python代码
protoc ./addressbook.proto --python_out=./
创建一个解析文件
protobufdemo.py
# -*- coding: utf-8 -*- # @Time : 2019-11-15 11:25 # @Author : cxa # @File : protobufdemo.py # @Software: PyCharm import addressbook_pb2 address_book = addressbook_pb2.AddressBook() person = address_book.people.add() person.id = 1 person.name = "cxa" person.email = "1@qq.com" person.money = 1234.00 person.work_status = True phone_number = person.phones.add() phone_number.number = "123456" phone_number.type = addressbook_pb2.MOBILE maps = person.maps maps.mapfield[1] = 1 maps.mapfield[2] = 2 # 序列化 serializeTostring = address_book.SerializeToString() # 生成字节数组 str_result = address_book.ParseFromString(serializeTostring) # 转为字符串 print(str_result) for person in address_book.people: print(person) for phone_number in person.phones: print(phone_number) for key in person.maps.mapfield: print(key, person.maps.mapfield[key])
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。