在 __init__.py 中递归填充 __all__

Dur*_*sun 3 python flask

我正在使用以下代码填充__all__我的模块__init__.py,如果有更有效的方法,我正在徘徊。有任何想法吗?

import fnmatch
import os

__all__ = []
for root, dirnames, filenames in os.walk(os.path.dirname(__file__)):
    root = root[os.path.dirname(__file__).__len__():]
    for filename in fnmatch.filter(filenames, "*.py"):
        __all__.append(os.path.join(root, filename[:-3]))
Run Code Online (Sandbox Code Playgroud)

ale*_*xis 5

您可能不应该这样做: 的默认行为import非常灵活。如果您不希望自动导出模块(或任何其他变量),请为其指定一个以 开头的名称,_python 不会导出它。这是标准的python方式,重新发明轮子被认为是非pythonic。另外,不要忘记模块之外的其他东西可能需要导出;设置后__all__,您还需要查找并导出它们。

尽管如此,您还是会问如何最好地生成可导出模块的列表。由于您无法导出不存在的内容,因此我只会检查您的主模块知道您自己的哪些模块:

basedir = os.path.dirname(__file__)
for m in sys.modules:
    if m in locals() and not m.startswith('_'): # Only export regular names
        mod = locals()[m]
        if '__file__' in mod.__dict__  and mod.__file__.startswith(basedir):
            print m
Run Code Online (Sandbox Code Playgroud)

sys.modules包括 python 已加载的每个模块的名称,包括许多尚未导出到主模块的名称——因此我们检查它们是否在locals().

这比扫描您的文件系统更快,并且比假设.py目录树中的每个文件都以某种方式最终成为顶级子模块更强大。自然地__init__.py,当所有内容都已加载时,您应该在.