【发布时间】:2015-03-06 18:22:41
【问题描述】:
我有一个 Python 项目,它使用 setuptools 进行部署,我主要关注this guide 关于项目结构。该项目使用 Google 协议缓冲区来定义网络消息格式。我的主要问题是如何让 setup.py 在安装过程中调用 protoc-compiler 以将定义构建到 _pb2.py 文件中。
在this question 中,建议将生成的 _pb2.py 文件与项目一起分发。虽然这可能适用于非常相似的平台,但我发现了一些不起作用的情况。例如,当我在使用 Anaconda Python 的 Mac 上进行开发并将生成的 _pb2.py 以及项目的其余部分复制到运行 Raspbian 的 Raspberry Pi 时,总是会出现来自 _pb2.py 模块的导入错误。但是,如果我在 Pi 上重新编译 .proto 文件,该项目将按预期工作。因此,分发编译文件似乎不是一种选择。
在这里寻找可行的最佳实践解决方案。可以假设目标平台已经安装了protoc-compiler。
编辑:
由于人们询问失败的原因。在 Mac 上,protobuf 版本是 2.6.1。在 Pi 上是 2.4.1。显然,生成的 protoc 编译器输出使用的内部 API 已经改变。输出基本上是:
File "[...]network_manager.py", line 8, in <module>
import InstrumentControl.transports.serial_bridge_protocol_pb2 as protocol
File "[...]serial_bridge_protocol_pb2.py", line 9, in <module>
from google.protobuf import symbol_database as _symbol_database
ImportError: cannot import name symbol_database
【问题讨论】:
-
我有类似的问题,总是在 PI 上编译。问题源于不同的 protobuf 版本。那么 - 你在各自的机器上有哪些版本,你不能将它们升级到相同的版本吗?
-
我真的很想避免这种情况。我可以(可能)在我控制的机器上做到这一点,但感觉不是正确的方法。将软件分发给其他人时,它可能会失败。当他们的当前版本可以(通过重新编译)使用时让他们安装特定版本的协议缓冲区,感觉不对。
-
您是否研究过 - 导致导入错误的原因?我会选择打包_pb2.py文件策略和研究导入错误问题。
-
满足用户的最低要求。因此,您要么要求他们安装某些软件,要么将其捆绑在您的应用程序中。您可以选择某个版本的协议缓冲区并将整个堆栈包含在您的产品中。只需确保在导入时先将其拾取即可。
-
@deets:我尊重这种观点,它肯定会让我的生活更轻松。但是,如果我可以从设置脚本中调用 protoc,那么特定的 protobuf 版本并不是真正的要求。并且将来当内部 API 再次更改并且突然用户需要运行旧版本时,将特定的固定版本作为要求可能会更加成问题。我真的很想避免那种支持地狱。所以让我们假设分发 _pb2.py 文件不是一个实际的选择。
标签: python installation protocol-buffers setuptools software-distribution