如何在python中更改现有第三方库中的函数

如何在python中更改现有第三方库中的函数,python,Python,这是向我提出的一个面试问题。如果没有道理,请不要惩罚我。她问: “我在python中有一个现有的第三方库,其中有一个函数foo()。在现有模块中导入后如何修改该函数?”这称为monkey patching。简言之,您可以只为保存函数的变量赋值: import existingmodule existingmodule.foo = lambda *args, **kwargs: "You fail it" 这在实践中很少是正确的答案。最好用自己的函数包装一些东西,或者在别处提供自己的实现,或者

这是向我提出的一个面试问题。如果没有道理,请不要惩罚我。她问:


“我在python中有一个现有的第三方库,其中有一个函数foo()。在现有模块中导入后如何修改该函数?”

这称为monkey patching。简言之,您可以只为保存函数的变量赋值:

import existingmodule

existingmodule.foo = lambda *args, **kwargs: "You fail it"
这在实践中很少是正确的答案。最好用自己的函数包装一些东西,或者在别处提供自己的实现,或者使用继承(如果是类上的方法)


这样做的唯一原因是,如果您需要在库自己的代码(或其他第三方代码)中反映更改的行为;如果是的话,好好测试一下。这通常比创建自己的叉子更好;也就是说,将代码作为补丁提交可能是一个好主意,因此,如果项目接受它,那么不仅仅是您支持它。

最常见的方法是(请参阅:)

例如:

>>> import os
>>> os.listdir('.')
['file_a', 'file_b']
>>> os.listdir = lambda folder: ['nothing in here, nope!']
>>> os.listdir('.')
['nothing in here, nope!']
在PyCon 2012上有一个非常好的主题,你可以观看

该演讲还提供了一个非常好的例子,说明猴子补丁在哪些方面是有用的: 假设您有一个第三方库,它可以做某些事情。要做到这一点,该脚本需要以root身份运行,但实际的功能不需要root权限。现在,第三方库可能正在使用
os.geteuid()==0
检查这一点。 通过在使用此库的代码中进行猴子补丁,您可以覆盖
geteuid
以冒充root来解决此限制


使用monkey补丁是一种快速修复库的好方法。提交错误报告并等待修补程序可能需要一段时间,因此您可以这样做,而不必深入库源代码。

我想,使用包装器函数。这不是做任何事情的“好方法”。有时这是做某事的唯一或最不复杂的方式。