我对协议缓冲区和python相对陌生,所以我偶然发现了下面描述的问题。(我在这个问题上做了很多研究,但没有找到解决方案(
我的代码的相关层次:
.
└── MainFolder
├── main.py
├── create_python_proto.bat
├── protos
│ └── foo.proto
├── client
│ ├── protos
│ │ ├ __init__.py
│ │ ├ foo_pb2.py
│ │ └ foo_pb2_grpc.py
│ ├── __init__.py
│ ├── client.py
│ └── etc...
└── server
├── ...
(main.py是我的起点(
当我用protoc从protobuf创建代码时,文件被正确放置,就像我希望的那样。但是我的"foo_pb2_grpc.py"中自动生成的代码不正确,确切地说是导入了"foo_pb2.py"。
实际状态:
from protos import foo_pb2 as protos_dot_foo__pb2
目标状态:
from ..protos import foo_pb2 as protos_dot_foo__pb2
我通过下面的命令"create_python_proto.bat"创建proto文件:
setlocal
python -m grpc_tools.protoc -I . --python_out=.client --grpc_python_out=.client protosfoo.proto
endlocal
所以当我从"main.py"运行程序时;ImportError";在"foo_pb2_grpc.py"中显示:
"无法从"protos"(未知位置(导入名称"foo_pb2">
我做错了什么?我正在拼命寻找解决方案,但就是找不到。。。
谢谢你提前帮我!
ps:两个'_int_.py'都在'中给出。\MainFolder\client"one_answers"。\MainFolder\client\protos为空
根据我的经验,在protoc
生成的Python中使用模块是困难的,最好避免。
gRPC repo的示例避免使用模块(可能是因为这个原因(。
一个解决方案是:
- 创建一个真正的模块源,例如
src
- 手动修改
foo_pb2_grpc.py
导入路径 - 使用绝对|相对
import
引用
使用:
src
├── client
│ ├── __init__.py
│ └── main.py
├── __init__.py
├── protos
│ ├── foo_pb2_grpc.py
│ ├── foo_pb2.py
│ └── __init__.py
└── server
├── __init__.py
└── main.py
和:
python
-m grpc_tools.protoc
--proto_path ${PWD}/protos
--python_out=${PWD}/src/protos
--grpc_python_out=${PWD}/src/protos
${PWD}/protos/foo.proto
和src/protos/foo_pb2_grpc.py
:
from ..protos import foo_pb2 as foo__pb2
或者:
import src.protos.foo_pb2 as foo__pb2
例如src/server/main.py
:
from ..protos import foo_pb2
from ..protos import foo_pb2_grpc
或from src.protos import ...
注意protoc
生成的包表示对等端(客户端|服务器(之间的接口。如果这些文件由第三方提供,则生成的文件将位于一个完全不同的模块(com.third.party
(中。对于内部原型,您可能希望遵循类似的做法。至少,将它们放在它们的客户端和服务器实现旁边(此处为src.protos
(。