python - 如何覆盖第三方库使用的方法
问题描述
这将是布局
some_function.py
def some_function():
print("some_function")
some_library.py
from some_function import some_function
class A:
def xxx(self):
some_function()
主文件
from some_library import A
from some_function import some_function
def new_some_function():
print("new_some_function")
if __name__ == '__main__':
some_function = new_some_function
a = A()
a.xxx()
在类A
中,方法xxx
,调用some_function
,那么是否可以用其他东西覆盖它,而无需重新实现整个类?
解决方案
您在这里提供的关于您的用例的信息非常少。正如其中一条评论指出的那样,这可能是继承的情况。如果您在测试环境中,您可能不想使用继承,但您可能更愿意使用模拟对象。
这是继承版本:
from some_library import A
def new_some_function():
print("new_some_function")
class B(A):
def xxx(self):
new_some_function()
if __name__ == '__main__':
a = B()
a.xxx()
请注意,类如何通过语句B
从类派生。这样,类继承了所有的功能,类的定义只包含与 不同的部分。在您的示例中,这就是该方法应该调用而不是.A
class B(A)
B
A
B
B
A
xxx
new_some_function
some_function
这是模拟版本:
from unittest import mock
from some_library import A
def new_some_function():
print("new_some_function")
if __name__ == '__main__':
with mock.patch('some_library.some_function') as mock_some_function:
mock_some_function.side_effect = new_some_function
a = A()
a.xxx()
如上所述,如果您在测试环境中并且如果some_function
做一些代价高昂和/或不可预测的事情,这种方法最有用。为了测试涉及对 的调用的代码some_function
,您可能暂时想用some_function
其他东西替换,即调用成本低且行为可预测。事实上,对于这种情况,替换some_function
为new_some_function
甚至可能比实际需要的要多。也许,您只想要一个可以调用并且始终返回相同值的空外壳(而不是side_effect
行,您可以指定一个常量.return_value
在上面的代码示例中)。模拟对象的关键功能之一是您可以稍后检查该函数是否已被调用。如果测试是您的用例,我非常建议您查看 python 模拟模块的文档。
请注意,该示例使用mock.patch
上下文管理器。这意味着在托管上下文中(即 - 语句中的块with
)some_library.some_function
被模拟对象替换,但是一旦您离开托管上下文,原始功能就会恢复原状。
推荐阅读
- laravel - 如何使用 laravel api 在数据库中上传多张图片
- java - 在 Java 中格式化浮点数 (#.###.##)
- php - 在while循环中获取当前帖子类别名称
- powershell - Get-ChildItem 和“DIR”返回不同的文件/文件夹计数?
- sapui5 - SAPUI5 List Item上下文绑定,获取下一个路径
- c - 如何将数据(行)添加到 GtkListBox (C)
- python - 无法在 appium/python 中找到元素
- ios - 如何使用 cocoapods 和工作区构建一个反应原生项目?
- javascript - Intro.Js 无法在 PHP 上运行
- typescript - 如何在 TypeScript 中使用本地库开发项目?