如何在__init__.py中正确扩展变量__all__?

时间:2017-10-20 01:38:13

标签: python import

在看到numpy \ __ init__.py库中的代码后,我自己写了__init__.py时感到很困惑。

这是numpy \ __ init__.py代码段

__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 import 的模块。 AttributeError:模块'lib1'没有属性'Sublib1File'

我的问题是

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

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

  3. 如果我们无法解决问题2,那么numpy \ __ init __中__all__.extend(...)的目的是什么?

3 个答案:

答案 0 :(得分:2)

如果再看一下numpy的顶级__init__模块,您会看到用于扩展from . import xyz的每个__all__的模块那里有一个相应的from .xyz import *

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

from .sublib1 import *的{​​{1}}下方添加from . import sublib1

另见:Can someone explain __all__ in Python?

答案 1 :(得分:1)

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

from .sublib1 import *

使示例有效。

答案 2 :(得分:0)

你是对的@Wyatt,@ MegaIng。

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

Q1。为什么即使lib1__init __。py?

中的__all__ = ['Lib1File', 'Sublib1File']也出现此错误

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

Q2。如果我仍然只使用一个import from lib1 import *

,我该如何解决?

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

Q3。 __all__.extend(...)numpy\__init__的目的是什么?

A3。为了扩展__all__灵活性。