在包内导入protobuf生成的模块
这是我的目录结构。
.
|-- A
| |-- B
| | `-- b.proto
| `-- C
| `-- c.proto
`-- py_gen
我这样编译 test.proto 文件。
protoc --python_out=py_gen/ --proto_path ${ROOT}/A ${ROOT}/A/B/b.proto \
${ROOT}/A/C/c.proto
这是我得到的结果。
.
`-- py_gen
|-- B
| `-- b_pb2.py
`-- C
`-- c_pb2.py
一切都运行得很好,我可以导入每个模块并使用它们,只要我在我的 PYTHONPATH 中包含 ${ROOT}/A/B/py_gen/B 和 ${ROOT}/A/B/py_gen/C。
问题出现在,比如说,模块 c 导入了 b。这在生成的代码中意味着 c 需要导入
import B.b_pb2
这是预期的结果,因为“在 Python 中,包通常是通过目录结构来确定的”(来自 protobuf 教程)。但是,我无法导入模块 c,因为它找不到 B.b_pb2.py。目前,为了让它正常工作,我必须在生成的目录 B 和 C 中添加空的 __init__.py 文件。
那么,为什么在生成的目录结构中没有 __init__.py 呢?我是不是忘记了什么?我对 Python 还很陌生,可能在这里忽略了一些明显的东西。不过我读了 Python 的 教程。
__init__.py 文件是必需的,以便让 Python 将这些目录视为包含包。
1 个回答
3
简单来说:
import B.b_pb2
这里不需要加 .py
后缀。而且,要让这个工作,B
目录里必须有一个 __init__.py
文件,这个文件可以是空的。这个文件告诉 Python 这是一个 包 目录。根据我所知道的,protobuf 不会在里面放 __init__.py
文件,但其实也不需要,因为它的目的是只为你生成一个单独的模块。