Python与Haskell进程间通信的IPC库有哪些?

6 投票
2 回答
1184 浏览
提问于 2025-04-17 10:22

我在考虑下一个项目的整体架构。对于后端,Haskell看起来非常合适,但前端用Python会更好,而且可能更容易编写代码。重的计算会在Haskell中完成,结果会在用Python构建的图形界面中显示。

所以,我需要选择合适的方式和格式来让这两个过程之间进行沟通。

从Python发送到Haskell的消息会很简单,就像一个包含几个不同值的文档。(我想可以用json格式来处理这个。)

但是,从Haskell发送到Python的消息会复杂得多,包含大量的(浮点)数组。这就是我需要更加小心的地方:无论我使用什么库,都需要在Python中实现得快,并且在Haskell中要相对稳定。

那么,我有哪些选择呢?

2 个回答

5

我建议你可以使用 Haskell 的 cerealblaze-builder 这两个包来定义你自己的二进制序列化格式,然后再写代码在 Python 中手动解包(比如用 struct)。如果你要传输的结构很多,这可能会比较麻烦,但如果只有一两个结构,这样做可能比找一个在两种语言中都支持得好的二进制序列化格式要简单和紧凑。

cereal 处理序列化和反序列化,而 blaze-builder 只处理序列化;不过我觉得 blaze-builder 的速度更快。cereal 的主要目的是以一种你不太挑剔的格式进行序列化,以便你可以在 Haskell 中稍后读取,这意味着它广泛使用了类型类,所以你需要小心使用一些标准序列化方式,这些方式可能会做一些不太好的事情,比如序列化任意大小的 Integer 而不是固定大小的整数,而 blaze-builder 更关注自定义格式。不过,使用 cereal 处理自定义格式还是相对简单的,如果你也想从 Haskell 中反序列化这些结构,它就是显而易见的选择。

快速浏览 Hackage,可以看到一个维护良好的 BSON 包;如果你的结构比较复杂,这可能是一个不错的选择,但如果不复杂,可能就有点过了。

我觉得用 JSON 来进行 Python→Haskell 的传输可能是最好的主意;虽然这样你就失去了在两个方向上使用相同序列化格式的好处,但 JSON 是非常标准的,并且在 Haskell 中得到了很好的支持,使用的是 aeson。如果你选择 BSON 来进行 Haskell→Python 的传输,这也可以。

我想到的其他选项有:

  • Hackage 上有两个名字很相似的 Apache Thrift 绑定:Thriftthrift;看起来前者正在被后者取代。不过我对 Thrift 了解不多,所以不能说这是否有帮助。
  • 你可以通过 cpythonMissingPy 将 Python 代码嵌入到 Haskell 进程中(不过后者似乎没有维护)。
  • 你可以使用 FFI 从 Haskell 导出函数,然后通过 ctypes 从 Python 中导入这些函数。
6

我在公司里使用谷歌的协议缓冲区(protocol buffers)和zeromq来处理数据。这两者之间可以很顺利地在Python、C++和C#代码之间传递数据,我也试过用Haskell,效果也不错。

其实可以把这个问题分成两个部分:序列化和传输。

正如ehird提到的,序列化有很多选择。我个人推荐使用协议缓冲区,因为我用得比较多。不过我也听说过thrift的评价不错,还有msgpack.org,看起来也很靠谱。

至于传输,我绝对推荐zeromq,真的是太棒了!它支持多种消息传递方式,而且速度非常快。这里有一个关于zmq资源和接收器的小例子,使用的是conduit库(我还没发布): https://github.com/boothead/zeromq-conduit

撰写回答