如何使用Python单元测试文档中推荐的延迟导入方法?

3
Python的文档指出,有一种替代本地导入的方法可以防止在启动时加载模块:

https://docs.python.org/3/library/unittest.mock-examples.html#mocking-imports-with-patch-dict

为了避免“前期成本”,可以通过延迟导入的方式来解决这个问题。这也可以用比无条件本地导入更好的方法来解决(将模块存储为类或模块属性,并仅在首次使用时进行导入)。
我不理解括号中的解释。我该如何做到这一点?然而,无论我怎么想,似乎最终仍会产生本地导入。

写得不是很清楚。也许括号中的句子是“无条件本地导入”的例子,而不是相反的例子? - Håken Lid
@HåkenLid 在段落的前一部分中提到:“有时候这样做是为了防止循环依赖,而通常有更好的方法来解决这个问题(重构代码)”。所以我认为括号里面的意思就是解决方案。 - Eric
这很可能是指使用importlib通过import进行导入,具体请参见下面我的答案所述。 - IonicSolutions
1个回答

0
文档可能涉及使用 importlib.import_module,它公开了Python的import功能:
import importlib

class Example():

    TO_IMPORT = "os"  # the name of the module to lazily import
    __module = None

    def __init__(self):
        if self.__module is None:
            self.__module = importlib.import_module(self.TO_IMPORT)

请注意,这种方式只在首次实例化类时导入模块,并且不可用于全局命名空间。
此外,它允许您更改要导入的模块,这在将同一类用作不同后端的接口时可能非常有用:
import importlib

class Example():

    def __init__(self, backend="some_module"):
        self.module = importlib.import_module(backend)

你为什么认为使用 importlib 是一个误导? - IonicSolutions
我不同意动态导入是 importlib 的唯一目的。文档中包含了很多提示,说明该模块可以用于什么以及为什么它被包含在 Python 中。在你的问题中,你要求澄清你引用的句子,我已经为你提供了一个我认为原始作者的意思的例子。他们明确说明了为什么使用 importlib 对单元测试有益。如果你不同意他们的观点,你可以继续使用 import 语句。 - IonicSolutions
等一下,他们具体在哪里说明importlib对单元测试有益?我在importlib文档中使用ctrl-f搜索“unit”,但没有找到任何内容,在unittest文档中使用ctrl-f搜索“importlib”,也没有找到任何内容。 - Eric
你问了unittest文档的作者想表达什么,我向你解释了他们可能的意思:如果将模块存储为类属性,那么在测试时用mock轻松替换(“patch out”)该模块。他们认为如果模块在全局命名空间中,这将更加困难,并提供了相应的解决方案。 - IonicSolutions
显示剩余7条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接