Pickling/unpickling 替代(API 兼容)class 实现
Pickling/unpickling alternative (API-compatible) class implementations
在分布式计算项目中,我们使用 Pyro 在节点之间通过线路传递对象; Pyro 在内部使用 pickle 序列化和反序列化对象。
项目中有些类有两种实现:一种是pure-Python(为了安装方便,特别是Windows用户),一种是c++/boost::python(快得多,但需要 boost + 如何编译扩展模块的知识)。 python 和 c++ 类 都支持酸洗(在 c++ 中,这是通过 boost::python 完成的)。
这些 类 具有不同的完全限定名称(mupif.Octree.Octant
与 mupif.fastOctant.Octant
),但后者是前者的别名并覆盖了纯 Python定义 (mupif.Octree.Octant=mupif.fastOctant.Octant
),因此它对用户是透明的,并且如果在节点上可用,则始终使用快速变体。
但是,pickle 使用 __module__
和 __class__
来标识实例,因此当基于 c++ 的对象通过线路传递到另一个不支持它的节点时,unpickling 将失败。
有什么解决办法?是否可以更改班级的 __module__
,即 foo.fastOctant.Octant.__class__.__module__='mupif.Octree'
?它会不会有一些我还没有看到的副作用?
如果没有可用的快速实现,以另一种方式(快速 = 正常)别名是否有帮助?也许这可以只在 unpickling 时完成,然后反转,以避免在其他代码中混淆检查?
在分布式计算项目中,我们使用 Pyro 在节点之间通过线路传递对象; Pyro 在内部使用 pickle 序列化和反序列化对象。
项目中有些类有两种实现:一种是pure-Python(为了安装方便,特别是Windows用户),一种是c++/boost::python(快得多,但需要 boost + 如何编译扩展模块的知识)。 python 和 c++ 类 都支持酸洗(在 c++ 中,这是通过 boost::python 完成的)。
这些 类 具有不同的完全限定名称(mupif.Octree.Octant
与 mupif.fastOctant.Octant
),但后者是前者的别名并覆盖了纯 Python定义 (mupif.Octree.Octant=mupif.fastOctant.Octant
),因此它对用户是透明的,并且如果在节点上可用,则始终使用快速变体。
但是,pickle 使用 __module__
和 __class__
来标识实例,因此当基于 c++ 的对象通过线路传递到另一个不支持它的节点时,unpickling 将失败。
有什么解决办法?是否可以更改班级的 __module__
,即 foo.fastOctant.Octant.__class__.__module__='mupif.Octree'
?它会不会有一些我还没有看到的副作用?
如果没有可用的快速实现,以另一种方式(快速 = 正常)别名是否有帮助?也许这可以只在 unpickling 时完成,然后反转,以避免在其他代码中混淆检查?