【问题标题】:How to correctly extend variable __all__ in a __init__.py?如何在 __init__.py 中正确扩展变量 __all__?
【发布时间】:2018-04-01 03:49:59
【问题描述】:

当我看到 numpy\__init__.py 库中的代码后尝试编写自己的 __init__.py 时,我感到很困惑。

这里是 numpy\__init__.py 代码 sn-p

__all__.extend(['__version__', 'pkgload', 'PackageLoader',
           'show_config'])
__all__.extend(core.__all__)
__all__.extend(_mat.__all__)
__all__.extend(lib.__all__)
__all__.extend(['linalg', 'fft', 'random', 'ctypeslib', 'ma'])

而我的目录结构是:

应用程序/

......test.py

......lib1\

............ __init__.py

............ Lib1File.py

............ sublib1\

……………………__init__.py

……………………SubLib1File.py

test.py中的代码是

from lib1 import *

if __name__ == "__main__":
    result1 = Lib1File.add(10, 15)    # a simple function in Lib1File.py
    print(result1)
    result2 = Sublib1File.mul(10,15)  # a simple function in Sublib1File.py
    print(result2)

lib1\__init__.py 中的代码是

from . import sublib1
__all__ = ["Lib1File"]
__all__.extend(sublib1.__all__)
print(__all__)                 # it can print ['Lib1File', 'Sublib1File'] on console

lib1\sublib1\__init__.py 中的代码是

__all__ = ["Sublib1File"]

但是当我运行 test.py 时,我得到了一个错误

*文件“test.py”,第 1 行,在模块中从 lib1 导入 。 AttributeError: 模块 'lib1' 没有属性 'Sublib1File'

我的问题是

  1. 为什么即使在 lib1\__init__.py 中 __all__ = ['Lib1File', 'Sublib1File'] 也会出现此错误?

  2. 如果我仍然只使用一个导入from lib1 import *,我应该如何解决它?

  3. 如果我们不能解决问题2,那么在numpy\__init__中__all__.extend(...)的目的是什么?

【问题讨论】:

    标签: python import


    【解决方案1】:

    如果您再看一下 numpy 的顶级 __init__ 模块,您会发现每个用于扩展 __all__from . import xyz 都有一个对应的 from .xyz import *

    如果相应的对象既没有在模块本身中定义也没有从其他地方导入,那么向模块的__all__ 添加名称是没有意义的。 __all__ 语句不会单独导入任何内容。

    lib1/__init__.py 中的from . import sublib1 下方添加from .sublib1 import *

    另见:Can someone explain __all__ in Python?

    【讨论】:

    • 是的,我注意到了。但我仍然不知道如何解决这个问题。你能给我更具体的修改吗?谢谢
    【解决方案2】:

    扩展@wyatts 答案,在lib1/__init__.py 中添加以下行:

    from .sublib1 import *
    

    使示例工作。

    【讨论】:

      【解决方案3】:

      你是对的@Wyatt,@MegaIng。

      我在这里发布三个问题的答案,以防其他人需要。

      第一季度。为什么即使在 lib1__init__.py 中 __all__ = ['Lib1File', 'Sublib1File'] 也会出现此错误?

      A1。因为您只需将模块名称添加到 __all__。但它实际上在lib1 目录中没有SublibFile 模块。所以python不能仅仅通过模块名找到SublibFile模块的定义。

      第二季度。如果我仍然只使用一个import from lib1 import *,我应该如何解决它?

      A2。在lib1/__init__.py 中添加一行from .sublib1 import *。这会将__all__中定义的模块放入lib1\sublib1\__init__.pylib\包中,以便python可以通过模块名称找到对应的模块定义。

      第三季度。 numpy\__init__中的__all__.extend(...)的目的是什么?

      A3。为了扩展__all__ 的灵活性。

      【讨论】:

        猜你喜欢
        • 2022-01-06
        • 1970-01-01
        • 1970-01-01
        • 2012-02-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-12-03
        • 2020-03-02
        相关资源
        最近更新 更多