8

简单来说

当模块 A 的功能应该是可导入的时,我如何从模块 B 修补模块 A,以便我可以使用multiprocessing标准库包运行模块 A 的功能?

背景

一个客户请求了一个不适用于我们任何其他客户的修补程序,因此我创建了一个新分支并为他们编写了一个单独的模块,以便轻松合并来自主分支的更改。为了保持客户端与预修补程序行为的向后兼容性,我将修补程序实现为应用程序中的可配置设置。因此我不想替换我的旧代码——只需在打开设置时对其进行修补。我通过猴子修补来做到这一点。

代码结构

__main__模块读入配置文件。如果配置打开了修补程序的开关,则通过用模块中定义的代码替换几个函数来__main__修补我的模块——本质上,被替换的函数是最大化函数的关键函数。该模块稍后会加载一个工人池。enginehotfixenginemultiprocessing

问题

一旦multiprocessing工作人员开始工作,它首先multiprocessing重新导入*engine模块并查找__main__试图替换的关键函数(然后multiprocessing将控制权交给我的代码并开始最大化算法)。由于engine正在由一个全新的进程重新导入并且新进程不会重新运行__main__(读取配置文件的位置),因为这会导致无限循环,因此它不知道 re-monkey-patch engine

问题

如何在我的代码中保持模块化(即,将修补程序代码保存在单独的模块中)并仍然利用 Python 的multiprocessing包?

* 请注意,我的代码必须在 Windows(对于我的客户端)和 Unix(对于我的理智......)

4

3 回答 3

1

这听起来像是猴子修补不起作用的地方。将相关功能提取到单独的模块并让引擎从那里导入它们更容易。也许您可以对从何处导入它们进行配置设置。

另一种模块化的方法是使用某种组件架构,比如ZCA。最后一个选项是我会选择的,但那是因为我已经习惯了,所以对我来说没有额外的学习。

于 2012-09-15T06:12:25.193 回答
1

要使其在具有 的 UNIX/Linux 操作系统上运行fork(),您不需要做任何特别的事情,因为新进程可以访问与父进程相同的(猴子补丁)类。

要使其在 Windows 上运行,请让您的__main__模块在导入时读取配置(将read_config/patch_engine调用置于全局范围内),但在if __name__ == '__main__'警卫中执行多处理(引擎执行)。

__main__然后,无论何时导入(从命令行或从multiprocessing重新导入),都会执行 read-config 代码,但if __name__ == '__main__'仅当从命令行调用脚本时才会执行代码(因为__main__在不同的名称下重新导入子进程)。

于 2012-09-17T18:51:55.137 回答
0

听起来您将不得不修改engine.py以检查配置文件,并在需要时对其进行修补。

要在 unix 和 Windows 上工作,engine可以保留一个全局CONFIG_DONE变量来决定是否需要再次检查配置文件。

于 2012-09-14T22:04:46.503 回答