【问题标题】:Python pkgutil.walk_packages not returning subpackagesPython pkgutil.walk_packages 不返回子包
【发布时间】:2020-09-12 00:43:44
【问题描述】:

我有一个包布局:

scenarios/
    __init__.py
    X/
        __init__.py
        Y/
            __init__.py
    Z/
        __init__.py 

我已经执行了

import scenarios
pkgutil.walk_packages(scenarios.__path__, scenarios.__name__ + '.')

但这会生成一个列表,其中仅包含包 X 和 Z,缺少 Y。我可以使用什么来获取所有子目录?

谢谢

【问题讨论】:

    标签: python packages


    【解决方案1】:

    这是一个理论:walk_packages 函数尝试导入列出的每个模块。当它到达子包“Y”时,它会尝试导入它,但出现错误。默认情况下,此错误被抑制。一个副作用是 walk_packages 函数不会递归到 Y。您可以使用“onerror”关键字参数来测试这个理论。例如:

    import sys, pkgutil
    from traceback import print_tb
    
    def onerror(name):
        print("Error importing module %s" % name)
        type, value, traceback = sys.exc_info()
        print_tb(traceback)
    
    import scenarios
    pkgutil.walk_packages(scenarios.__path__, scenarios.__name__ + '.', onerror=onerror)
    

    【讨论】:

    • 谢谢,我没有意识到它在导入错误时静默失败。我的问题是我的包不在我的 sys.path 上
    【解决方案2】:

    这至少在 Python 3.6 中有效,值得。设置测试场景:

    mkdir -p scenarios/X/Y scenarios/Z
    find scenarios -type d -exec touch {}/__init__.py \;
    

    现在运行您的示例代码的一个版本:

    import pkgutil
    import scenarios
    for module_info in pkgutil.walk_packages(scenarios.__path__, scenarios.__name__ + '.'):
        print(module_info.name)
    

    哪些打印:

    scenarios.X
    scenarios.X.Y
    scenarios.Z
    

    【讨论】:

    • 尽管 Python >= 3.3 支持 implicit namespace packages 不需要 __init__.py,但我发现它们是必需的,以便 pkgutil.walk_packages 成功递归到子包中
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多