2017-10-20 70 views
0

当我在numpy \ __ init__.py库中看到代码后,试图自己写__init__.py时,我很困惑。如何在__init__.py中正确地扩展变量__all__?

这里是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导入。 AttributeError的:模块 'LIB1' 有没有属性 'Sublib1File'

我的问题是

  1. 为什么我在LIB1 \ __ init__.py得到这个错误,即使__all__ = ['Lib1File', 'Sublib1File']

  2. 我应该如何修复它,如果我仍然只使用一个进口from lib1 import *

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

回答

1

如果你再看看numpy的顶尖级__init__模块,你会看到每个from . import xyz这是我们用来扩展__all__有一个相应的from .xyz import *

如果相应的对象没有在模块本身中定义或从其他地方导入,则为模块的__all__添加名称将不起作用。

添加from .sublib1 import *低于from . import sublib1lib1/__init__.py

+0

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

1

扩展@wyatts回答,添加以下行lib1/__init__.py

from .sublib1 import * 

为了让这个例子的工作。

0

你是对的@Wyatt,@MegaIng。

我在这里回答了三个问题的答案,以防万一别人需要它。

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

A1。因为您只需将模块名称添加到__all__。但实际上lib1目录中没有SublibFile模块。所以Python无法找到模块名称的SublibFile模块的定义。

Q2。我应该如何修复它,如果我仍然只使用一个import from lib1 import *

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

Q3。 __all__.extend(...)numpy\__init__中的用途是什么?

A3。为了延伸__all__的灵活性。