如何在Python项目中使用PyPI依赖的Protobuf生成代码?
解决Protobuf生成代码的导入路径问题
不需要重复生成所有依赖代码,有几种可行的解决方案:
方案一:在依赖的proto文件中指定Python包名(推荐)
如果foo_lib是你维护的项目,修改foo.proto,添加py_package选项指定生成代码所属的Python包:
syntax = "proto3"; package foo; option py_package = "foo_lib"; // 指定生成的Python代码归属于foo_lib包 message Foo { string bar = 1; }
重新生成foo_lib的代码并更新私有PyPI仓库。之后再编译bar.proto时,protoc会自动生成正确的导入语句:
import foo_lib.foo_pb2 as foo__pb2
完全匹配PyPI包的路径结构,解决导入错误。
方案二:使用protoc的导入映射参数(无需修改依赖proto)
如果无法修改foo.proto(比如foo_lib由第三方维护),可以利用protobuf 3.19+版本支持的--import_map参数,直接在编译命令中映射proto文件到目标Python包路径:
python -m grpc_tools.protoc -I path/to/directory/where/bar.proto/is --import_map=foo.proto=foo_lib.foo_pb2 --python_out src/bar path/to/directory/where/bar.proto/is/bar.proto
这个参数会让protoc将原本生成的import foo_pb2 as foo__pb2替换为import foo_lib.foo_pb2 as foo__pb2,直接适配已安装的PyPI包结构。
临时方案:手动修改生成代码
如果上述两种方案都无法使用,也可以手动修改bar_pb2.py中的导入语句,将:
import foo_pb2 as foo__pb2
改为:
from foo_lib import foo_pb2 as foo__pb2
这种方法简单直接,但每次重新生成代码后都需要重复修改,适合临时测试场景。
内容的提问来源于stack exchange,提问作者rabejens
相关产品推荐
相关产品推荐

