protobuf软件包如何使用?

时间:2019-01-30 06:47:23

标签: c# python-3.x package protocol-buffers

我不了解Google的Python protobuf文档中软件包的最后一句话的第一部分:

  

.proto文件以程序包声明开头,这有助于防止不同项目之间的命名冲突。在Python中,包通常由目录结构决定,因此您在.proto文件中定义的包对生成的代码无效。但是,您仍然应该声明一个以避免协议缓冲区名称空间和非Python语言中的名称冲突。

在Python中(可能是在使用名称空间的语言中)“ 您在.proto文件中定义的包对生成的代码没有影响”实际上是错误的,因为生成的..._pb2.py文件包含具有包字段的描述符。

DESCRIPTOR = _descriptor.FileDescriptor(
  name='example.proto',
  package='example',
  syntax='proto3',
   ...
)

我已经检查过,并且在生成代码后您无法import example进入常规的python文件。例如,在package example;文件中声明.proto,然后protoc进行编译不会自动使您的包可用于环境中的python文件导入(您仍必须使用{{1} }来访问这些类。

有人能解释在import ..._pb2文件中声明的包如何在Python中使用,并说出C#作为显式使用名称空间的语言的示例吗?

1 个答案:

答案 0 :(得分:1)

引用文档本身:

在Python中,由于Python模块是 根据它们在文件系统中的位置进行组织。

那么包声明的用途到底是什么? 我相信两件事:

  1. 两个避免了在消息对象中命名冲突的可能性。如果假设您有一条消息在同一应用程序下以不同的方式声明,则可以考虑在原始文件的开头提供程序包说明符,然后在定义其他消息类型的字段时使用指定的程序包。例如,如果在Foopackage bar两者下都定义了package baz;然后在需要时使用bar.Foobaz.Foo

  2. 我认为的第二个原因是可移植性。 Package指令在Python和Golang中均被忽略。但是像C ++和C#这样的语言会显式创建名称空间,但它们确实会考虑指定的包。因此,对于以上示例中的Foo,将在Foobar的命名空间中声明名为baz的消息类型。使用Python应用程序创建的原型文件可以以几乎相同的方式为C#应用程序编译。应当指出,Protobuf是用于序列化和反序列化数据的语言不可知机制。

话虽如此,我个人还没有发现我的Python应用程序在protobuf消息中使用包说明符。

参考:https://developers.google.com/protocol-buffers/docs/proto