Reputation: 23
I'm confused when I tried write myself __init__.py after saw the code in numpy\__init__.py library.
Here is numpy\__init__.py code snippet
__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'])
And My directory structure is:
app/
......test.py
......lib1\
............ __init__.py
............ Lib1File.py
............ sublib1\
............ ............ __init__.py
............ ............ SubLib1File.py
The code in test.py is
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)
The code in lib1\__init__.py is
from . import sublib1
__all__ = ["Lib1File"]
__all__.extend(sublib1.__all__)
print(__all__) # it can print ['Lib1File', 'Sublib1File'] on console
The code in lib1\sublib1\__init__.py is
__all__ = ["Sublib1File"]
But when I ran test.py, I got a error
*File "test.py", line 1, in module from lib1 import . AttributeError: module 'lib1' has no attribute 'Sublib1File'
My questions are
Why I get this error even if __all__ = ['Lib1File', 'Sublib1File']
in lib1\__init__.py?
How should I fix it if I still just use one import from lib1 import *
?
If we cannot solve question 2, what's the purpose of __all__.extend(...)
in numpy\__init__?
Upvotes: 0
Views: 807
Reputation:
If you take another look at numpy's top-level __init__
module you'll see that for each from . import xyz
that's used to extend __all__
there's a corresponding from .xyz import *
.
Adding a name to a module's __all__
is meaningless if the corresponding object isn't either defined in the module itself or imported from somewhere else. The __all__
statement doesn't import anything on it's own.
Add from .sublib1 import *
below from . import sublib1
in lib1/__init__.py
.
Also see: Can someone explain __all__ in Python?
Upvotes: 2
Reputation: 23
you are right @Wyatt, @MegaIng.
I post my answer here for the three questions, just in case others need it.
Q1. Why I get this error even if __all__ = ['Lib1File', 'Sublib1File']
in lib1__init__.py?
A1. Because you just add module name to __all__. But it actually does not have SublibFile
module in lib1
directory. So python cannot find the definition of SublibFile
module just by the module name.
Q2. How should I fix it if I still just use one import from lib1 import *
?
A2. Add one line from .sublib1 import *
in lib1/__init__.py
. This will put modules that are defined in __all__
in lib1\sublib1\__init__.py
to lib\
package so that python can find correspondence module definition by the module name.
Q3. What's the purpose of __all__.extend(...)
in numpy\__init__
?
A3. In order to extend __all__
flexibility.
Upvotes: 0
Reputation: 7886
Extending @wyatts answer, add the following line in lib1/__init__.py
:
from .sublib1 import *
To make the example work.
Upvotes: 1