为何protoc.py在PowerShell中调用编译的outcome_pb.py代码缺失?
问题原因及解决方案
核心原因
你的Proto文件依赖了Google Protobuf的基础类型定义(比如google.protobuf.Empty、google.protobuf.Timestamp这类通用类型),这些定义默认存放在grpc_tools库自带的_proto目录中。
你修改后的protoc.py注释掉了原版脚本自动添加该目录为搜索路径的逻辑,导致:
- PowerShell调用
protoc.py时,protoc无法找到这些基础类型的定义,只能生成Proto文件中不依赖基础类型的部分代码,所以outcome_pb.py体积骤减、功能缺失。 outcome_pb_grpc.py不受影响,是因为你的GRPC服务定义没有依赖这些基础Protobuf类型,生成服务代码时不需要解析这些依赖。- 在PowerShell中直接调用Python脚本也出问题,本质是你之前的Python脚本能正常生成是巧合——要么你的
<MyProtoDirectory>里手动放了基础类型的Proto文件,要么Python环境通过其他方式让main函数找到了这个路径;但通过python protoc.py调用时,缺失了关键的搜索路径参数。
修复方案
方案1:恢复原版protoc.py逻辑
把你修改的protoc.py改回原版(补全缺失的import语句):
import sys import pkg_resources from grpc_tools.protoc import main if __name__ == '__main__': proto_include = pkg_resources.resource_filename('grpc_tools', '_proto') sys.exit(main(sys.argv + ['-I{}'.format(proto_include)]))
这样PowerShell调用protoc.py时会自动添加基础类型的搜索路径,生成完整的outcome_pb.py。
方案2:在PowerShell脚本中手动添加搜索路径
如果你不想修改protoc.py,可以在PowerShell调用时手动传入grpc_tools._proto的路径:
- 先获取该目录的绝对路径:
python -c "import pkg_resources; print(pkg_resources.resource_filename('grpc_tools', '_proto'))"
- 修改PowerShell脚本,添加
--proto_path参数指向该目录:
$tmp = (Get-Location).tostring() Set-Location -Path ('<MyProtoDirectory>') # 获取grpc_tools自带的基础proto目录 $protoInclude = python -c "import pkg_resources; print(pkg_resources.resource_filename('grpc_tools', '_proto'))" try { python '...\protoc.py' ` "--proto_path=." ` "--proto_path=$protoInclude" ` "--python_out=<MyOutputDirectory>" ` "--grpc_python_out=<MyOutputDirectory>" ` "<MyProto>" } finally { Set-Location -Path $tmp }
内容的提问来源于stack exchange,提问作者George Gayton
相关产品推荐
相关产品推荐

