python分配buffer_Python中的Protocol Buffer

Python部落(python.freelycode.com)组织翻译,禁止转载,欢迎转发。

Python中有一些对象可以访问底层的内存数组或缓冲区。这些对象包含内置字节和二进制数组,还有一些扩展,比如

array.array。为了满足特殊需求,如数字计算、模拟或图像处理,第三方库可以定义自己的类型。

这里我们将介绍如何使用Protocol Buffer,并将介绍:

在.proto文件中使用的几种消息格式。

如何使用Protocol Buffer编译器。

如何使用Protocol Buffer的API读写消息。

自定义.proto文件

要创建一个联系人应用,需要从.proto文件开始。这个文件包含定义。在.proto文件中,需要确定联系人的数据结构,然后添加名称和数据类型到相应的字段。

现在浏览上面代码段的每一部分并理解它的作用。

为了防止与其他项目发生任何类型的命名冲突,我们可以先创建一个包,再在包内创建文件。包名由文件目录结构确定。这样无论在.proto文件中定义任何包,都不会对代码产生影响。建议在Protocol Buffers命名空间中定义名字,即便你使用的不是Python(译者注:Protocol Buffers其他语言也能使用)。

下面的语句定义了一个message,里面只包含一些字段,这些字段类型可以是int32,float,string,bool。

还可以使用其他类型的字段为message添加更多结构。在上面的例子中,Person包含PhoneNumber,而AddressBook包含Person。如你所见,可以定义一些消息内嵌于其他消息,比如PhoneNumber在Person中定义。如果想让字段是预定义的列表值中的某个值,可以定义枚举类型,上面例子中是想定义电话号码是MOBILE,HOME或者WORK类型。

每个元素上的“= 1”,“= 2”是该字段在二进制编码中的唯一标识。

每个字段必须包含以下三个修饰符之一:

required: 必须提供该字段的值,否则该message将被视为“未初始化”。序列化未初始化的消息将引发异常,解析未初始化的消息将会失败。除此之外,required字段和optional字段作用相同。

optional:可选字段。如果该字段未赋值,将使用默认值。对于简单类型,可以自定义默认值,就像上例中的phone number type。否则,将使用系统默认值:数字类型是0,字符串类型是空串,布尔类型是false。对于内嵌的消息,默认值始终是消息的“default instance(默认实例)”或“prototype(原型)”,没有设置任何字段。调用访问器获得未设值的optional或required字段将返回默认值。

repeated:该字段可以重复任何次数(包括0)。重复值的顺序将保留在Protocol Buffer。将重复字段视为动态大小的数组。

编译Protocol Buffers

创建了.proto文件后,需要类来对AddressBook进行读写操作。为达到此目的,需要用Protocol Buffer编译器proctoc来编译运行.proto文件。

如果没有安装编译器,请按照README中的说明进行下载。

现在运行编译器,指定源代码目录(应用程序源代码所在位置,默认为当前目录),目标目录(生成的代码所在位置,通常和$SRC_DIR相同)和.proto目录。在这里使用:

因为是Python类,所以使用- -python_out设置;同理其他语言也如此设置。

这个addressbook_pb2.py文件将生成在指定的目标目录中。

Protocol Buffer API

java和C++的Protocol Buffer是自动生成的。可惜在Python中,Python的Protocol Buffer编译器不会自动生成数据访问代码,而会生成一个有自己解释方式的文件,可以称之为decipher。

_ _metaclass_ _ = reflection.GeneratedProtocolMessageType是很重要的一条语句,为创建类创建了模版。在加载时,GeneratedProtocolMessageType元类使用指定的描述符创建处理每个消息类型所需要的所有Python方法,并将它们添加到相关类中。以便可以在代码中使用完全填充的类。

现在你可以使用Person类,如同它将Message基类中的每个字段定义为常规字段。你可以按照以下代码示例编写:

扩展Protocol Buffer

在初次或几次实现发布后,可能需要改进Protocol Buffer的定义。如果想使新的Protocol Buffer向前向后兼容,需要遵循这些规则:不能改变任何操作字段的标签编号。

不能删掉任何现有字段或在缓存区中添加任何字段。

可以删除optional或replicated属性的字段。

可以添加新的optional属性的字段或repeated属性的字段但是必须创建一个新的标签编号。

如果遵循这些规则,你能做什么?

如果遵循这些规则,旧代码将容易阅读新消息,只忽略新字段。对于旧代码,已删除的optional属性的字段将只有默认值,repeated属性的字段将为空。 新代码依然会读取旧消息。但是,请记住,新的optional属性的字段将不会出现在旧消息中,所以需要使用has_明确地查看它们是否进行了设置,或者在.proto文件中的标签编号后面用[default=value]提供一个合理的默认值。如果未给optional属性的字段指定默认值,则会使用特定类型的默认值:对于字符串,默认值是空串。对于布尔值,默认值是false,对于数字值,默认值是0。还要注意,如果添加了新的repeated字段,新代码将无法确定它该设为空(根据新代码)还是不设值(根据旧代码),因为它没有has_标识。

希望你喜欢。英文原文:http://www.discoversdk.com/blog/protocol-buffer-in-python

译者:刘开心

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值