获取当前包中所有模块的列表

Posted

技术标签:

【中文标题】获取当前包中所有模块的列表【英文标题】:Getting a list of all modules in the current package 【发布时间】:2010-10-08 00:30:20 【问题描述】:

这就是我想做的事情:我想构建一个测试套件,该套件被组织成包,如 tests.ui、tests.text、tests.fileio 等。在这些包中的每个 __init__.py ,我想制作一个包含该包中所有模块中的所有测试的测试套件。当然,可以使用 unittest.TestLoader 完成所有测试,但似乎我必须单独添加每个模块。所以假设test.ui有editor_window_test.py和preview_window_test.py,我想要__init__.py导入这两个文件并得到两个模块对象的列表。我的想法是我想自动化测试套件的制作,这样我就不会忘记在测试套件中包含一些东西。

最好的方法是什么?这似乎是一件容易的事,但我什么也没找到。

顺便说一句,我正在使用 Python 2.5。

【问题讨论】:

与***.com/questions/912025/…几乎重复 【参考方案1】:

可以使用 os.listdir 查找 test.* 目录下的所有文件,然后过滤掉 .py 文件:

# Place this code to your __init__.py in test.* directory
import os
modules = []
for name in os.listdir(os.path.dirname(os.path.abspath(__file__))):
    m, ext = os.path.splitext()
    if ext == '.py':
        modules.append(__import__(m))
__all__ = modules

魔术变量__file__ 包含当前模块的文件路径。试试

print __file__

检查。

【讨论】:

(像 OP 想要的那样自动导入子模块有点不合时宜。将import a, b, c 放入 init.py 也同样简单)。无论如何,缺少步骤:modules.append(__import__(name)),然后是__all__ = modules 这似乎也是通过文件路径导入的,这只是因为 2.6 之前的 python 中的一个错误。 不是bug,是相对导入。【参考方案2】:

这里的答案很好,但最好的方法是使用 3rd 方测试发现和运行器,例如:

Nose(我的最爱) Trial(非常好,尤其是在测试异步内容时) py.test(在我看来不太好)

它们都与普通的 unittest.TestCase 兼容,您不必以任何方式修改您的测试,也不必使用其中任何一个中的高级功能。只需用作套件发现。

您是否有特定原因要重新发明这些库中的讨厌的东西?

【讨论】:

不,不是。我不知道他们。 :-)【参考方案3】:

从我们的 django 项目中解决这个问题:

"""Test loader for all module tests
"""
import unittest
import re, os, imp, sys

def find_modules(package):
    files = [re.sub('\.py$', '', f) for f in os.listdir(os.path.dirname(package.__file__))
             if f.endswith(".py")]
    return [imp.load_module(file, *imp.find_module(file, package.__path__)) for file in files]

def suite(package=None):
    """Assemble test suite for Django default test loader"""
    if not package: package = myapp.tests # Default argument required for Django test runner
    return unittest.TestSuite([unittest.TestLoader().loadTestsFromModule(m)
                               for m in find_modules(package)])

if __name__ == '__main__':
    unittest.TextTestRunner().run(suite(myapp.tests))

编辑:与 bialix 的解决方案相比的好处是您可以将此加载程序放置在项目树中的任何位置,无需在每个测试目录中修改 init.py。

【讨论】:

以上是关于获取当前包中所有模块的列表的主要内容,如果未能解决你的问题,请参考以下文章

R语言使用data函数获取当前R环境可用的示例数据集:获取datasets包中的所有示例数据集获取所有包的数据集获取特定包的数据集

获取数据包中的所有层

如何在 Python 中获取当前的导入路径?

os模块

获取当前目录中所有子目录的列表

获取当前目录中所有子目录的列表