如何避免将 _pb2.py 文件放在包根目录下?

How to avoid placing _pb2.py files at package root?

我在 Python 包中使用 libprotoc 3.2.0 和 Python 3。如果我尝试将 Protobuff Python 文件(用扩展名 _pb2.py 表示)放入它们自己的文件夹中,使用 .proto 文件,假设 protobufs 然后尝试导入他们的 python 文件如下:

# assuming outputs from a.proto and b.proto, where b depends on a
import protobufs.a
import protobufs.b

我收到 b 找不到 a 的导入错误。如果我将 _pb2.py 文件输出到我的包的根目录中,我就没有这个问题。 this issue 对此进行了详细说明,但我不确定我是否遇到了完全相同的问题。是否可以避免在我的包的根目录下输出 _pb2.py 文件?

非玩具示例

我实际拥有的是两个相互引用的 protobuff,如下 .proto 文件中所示:

syntax = "proto3";
import "common.proto";

在 Python 文件中,这被翻译成:

# Generated by the protocol buffer compiler.  DO NOT EDIT!
# source: persons.proto

import sys
_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1'))
from google.protobuf.internal import enum_type_wrapper
from google.protobuf import descriptor as _descriptor
from google.protobuf import message as _message
from google.protobuf import reflection as _reflection
from google.protobuf import symbol_database as _symbol_database
from google.protobuf import descriptor_pb2
# @@protoc_insertion_point(imports)

_sym_db = _symbol_database.Default()


import common_pb2 as common__pb2

但是因为文件位于 Python 包中名为 protobufs 的文件夹中,所以最后一行应该是 import protobufs.common_pb2 as common__pb2 而不是 import common_pb2 as common__pb2,而是 [=26] =]不知道文件夹怎么算。

解决方案实际上非常简单。 只需使用:

import "protobufs/common.proto";

这应该会导致您的 _pb2.py 文件包含导入 from protobufs import common_pb2 as protobufs_dot_common__pb2 而不是当前导入。

当然,您需要相应地更新编译器的命令行。符合以下内容:

protoc.exe protobufs\persons.proto --proto_path=. --python_out=.