【问题标题】:Cannot Import * from a Subdirectory in Python [duplicate]无法从 Python 中的子目录导入 * [重复]
【发布时间】:2020-10-25 23:33:23
【问题描述】:

我希望将一组模块从子目录导入到父目录中的单个主模块中:

项目/

main.py
subdirectory/
    __init__.py
    timer.py
    example.py

我可以要求任何单独的 .py 文件,如下所示:

from subdirectory import timer.py

但是,如果我运行以下命令,

from subdirectory import *

我尝试使用该子目录中的模块,我收到以下错误:

File "My:\Path\Here\...", line 33, in main
t = timer.timer()
NameError: name 'timer' is not defined

我希望能够一次导入所有文件,因为我正在导入几个模块。我已经在子目录中添加了一个空白的 init.py 文件。 我有什么遗漏的吗?

【问题讨论】:

    标签: python python-3.x


    【解决方案1】:

    您必须在 __init__.py 中使用 __all__ 声明您的模块名称:

    __init__.py:

    __all__ = ["timer", "example"]
    

    这种行为是documented:

    唯一的解决方案是包作者提供包的显式索引。 import 语句使用以下约定:如果包的 __init__.py 代码定义了一个名为 __all__ 的列表,则它被视为遇到 from package import * 时应导入的模块名称列表。

    【讨论】:

    • 非常感谢! import * 语句现在可以正常工作了,我可以使用我导入的模块了。
    【解决方案2】:

    如果您只想使导入工作,请添加 subdirectory/__init__.py 并包含以下内容:

    from * import example
    from * import timer
    

    但是,如果您想对任意数量的(旧的和新的)模块执行此操作,我认为 this answer 可能是您正在寻找的:

    您从以下结构开始:

    main.py
    subdirectory/
    subdirectory/__init__.py
    subdirectory/example.py
    subdirectory/timer.py
    

    然后从main.py导入subdirectory中的所有内容:

    from subdirectory import *
    t = timer.timer()
    

    然后将以下内容添加到subdirectory/__init__.py 模块中:

    from os.path import dirname, basename, isfile, join
    import glob
    modules = glob.glob(join(dirname(__file__), "*.py"))
    __all__ = [ basename(f)[:-3] for f in modules if isfile(f) and not 
    f.endswith('__init__.py')]
    

    为了完整起见,subdirectory/timer.py 模块:

    def timer():
        return 42
    

    【讨论】:

    • from * import example 是语法错误。我想你想要from . import example
    • 感谢您的回答。该来源确实有很好的解决方案。
    【解决方案3】:

    进口是这样的。

    # if you have timer.py, import it as 
    import timer
    

    尝试将__init__.py 添加到子目录中。 它现在看起来像:

    项目/

    
        main.py
        subdirectory/
                     __init__.py
                     timer.py
                     example.py
    

    如果这不起作用: 在main.py添加

    import sys
    sys.path.append("path/to/subdirectory") # replace with the path
    import timer
    

    【讨论】:

    • 我已经这样做了。
    猜你喜欢
    • 2021-10-06
    • 1970-01-01
    • 2011-05-11
    • 1970-01-01
    • 2021-10-23
    • 1970-01-01
    • 2013-03-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多