我知道,这个问题可能被问了很多次。我认为自己是 Python 的新手,有时我不太明白导入系统是如何工作的。特别是就我而言,如果没有我不想做的解决方法,我还没有找到任何解决方案。为什么?让我解释一下:
所以我有这个与 Google protobufs 一起使用的“程序”。当从给定的编译器(协议)创建 Python 代码时,它总是显示“请勿编辑!”。所以我不会编辑生成的代码,而且我真的不想这样做(必须有一个解决方案,而不必每次生成代码时都自己修复每个文件)。
这是我的项目的组织方式:
|root:
|---protos:
| |---API:
| | |---protoApiA.proto
| | |---protoApiB.proto ...
| |---common:
| |---protoCommonA.proto ...
|---src:
| |---__init__.py
| |---foo:
| | |---__init__.py
| | |---bar:
| | | |---main.py
| | | |---protos:
| | | | |---API:
| | | | | |---protoApiA_pb2.py
| | | | | |---protoApiB_pb2-grpc.py ...
| | | | |---common:
| | | | | |---protoCommonA_pb2.py
| | | | | |---....
|---test_script.py
protoApiA.proto 从 protoCommonA.proto 导入。
import "common/protoCommonA.proto";
解析为:
from common import protoCommonA_pb2 as common_dot_protoCommonA__pb2
使用以下 PowerShell 提示创建它们后:
& py -3.10 -m grpc_tools.protoc -I./protos --python_out=./src/foo/bar/protos/ --grpc_python_out=./src/foo/bar/protos/ common/protoCommonA.proto API/protoApiA.proto API/protoApiB.proto
到目前为止一切顺利。以下是初始化文件包含的内容:
# root/src/__init__.py:
from . import foo
# root/src/foo/__init__.py:
from .bar.main import ... #relevant functions for test_script.py
文件 main.py 需要使用 proto 文件来处理一些 gRPC 相关的东西。 文件 test_script.py 是一个脚本,它使用 main.py 中的一些功能,主要用于测试。
如果我通过 test_script.py 测试功能,它会在 protoApiA_pb2.py 上抛出“未找到模块”错误,因为它不知道 protoCommonA_pb2.py。
所以这是我的问题: 如何在不编辑任何自动生成的 Python 文件中的导入语句的情况下完成这项工作?
我了解了导入系统的工作原理,但我想我不明白它到底是如何工作的,因为在过去的三天里我无法想出任何解决方案。
提前致谢!希望有人可以向我解释为什么我会遇到这个问题以及如何正确解决它
所以,最后,我发现自己使用一个小脚本在创建生成的原型文件后立即自动编辑它们。
尽管 Google 广泛使用 Protobufs(显然),但他们的包内有一个扁平的层次结构,或者单独安装他们的原始包。因此,他们不会遇到这些问题,并且很可能不会进行修复(该问题自 2015 年以来一直存在)。