这是问我的一个面试问题。如果没有意义,请不要惩罚我。她问:
“我在 python 中有一个现有的 3rd 方库,其中有一个函数 foo()。导入现有模块后如何修改该函数?”
这称为猴子修补。简而言之,您可以只分配给持有该函数的变量:
import existingmodule
existingmodule.foo = lambda *args, **kwargs: "You fail it"
这在实践中很少是正确的答案。最好用自己的函数包装一些东西,或者在其他地方提供自己的实现,或者使用继承(如果是类上的方法)。
这样做的唯一原因是如果您需要将更改的行为反映在库自己的代码(或其他第三方代码)中;如果是这样,请好好测试。这通常是比创建自己的分叉更好的方法;也就是说,将您的代码作为补丁提交可能是一个好主意,因此如果它被项目接受,不仅仅是您支持它。
最常见的方法是猴子补丁(参见:stackoverflow:什么是猴子补丁)
例如:
>>> import os
>>> os.listdir('.')
['file_a', 'file_b']
>>> os.listdir = lambda folder: ['nothing in here, nope!']
>>> os.listdir('.')
['nothing in here, nope!']
在 PyCon 2012 上有一个关于这个主题的非常好的演讲,你可以在youtube上观看
该演讲还提供了一个很好的例子,说明猴子补丁在哪里有用:假设您有一个第三方库可以做某件事。要做到这一点,这个脚本需要以 root 身份运行 - 但实际功能不需要 root 权限。现在第三方库可能正在使用os.geteuid() == 0
. 通过在使用此库的代码中进行猴子修补,您可以覆盖geteuid
伪造为 root 以解决此限制。
使用猴子补丁是快速修复库的好方法。提交错误报告并等待补丁可能需要一段时间,因此您可以通过这种方式帮助自己,而无需深入研究库源代码。