folder structure:
<current dir>
main.py
packages <dir>
__init__.py
mod.py
main py:
import packages
print packages.mod.hello()
mod.py:
def hello():
return 'hello'
__init__.py:
from packages import mod
If I run main.py, I get no error. But if I edit __init__.py to 'from packages import *' , I get this error: AttributeError: 'module' object has no attribute 'mod'
I'm not asking how to make that 'print' command work. I can use other 'import' syntax in main.py to make it work. The question is: I'm curious about that 'from packages import mod' in the __init__.py. If i can do import mod then when I replace to import *, which means import everything, why do I get an error instead?
So what does the from packages import * really mean inside that __init__.py?
Anyone can help? Thanks
So what does the from packages import * really mean inside that __init__.py?
The __init__.py imports itself.
You can only import modules, not packages. Packages are just containers for modules or sub-packages. When you "import" a package you actually import the module __init__.py.
The __init__.py with this content:
from packages import mod
imports the module mod into __init__.py. Therefore, it will be available
in your main.py via packages.mod (remember packages is represented by __init__.py).
When you change the content of __init__.py to:
from packages import *
You are importing the module __init__.py, the very same file you are in.
This works (a second import just triggers a lookup in sys.modules)
but won't give you the content of mod.
This means, you can use:
from module import *
but you cannot sensibly use this with an empty __init__.py:
from package import *
Because package is actually represented by the __init__.py and there
is nothing in it yet. You can check this (interactively or in file):
>>> import packages
>>> print(packages)
<module 'packages' from '/.../packages/__init__.py'>
In __init__.py you can write:
from packages.mod import *
and then in main.py:
print packages.hello()
works. Because the function hello() is now in the global name space of the
file __init__.py.
As mentioned in the answer by mozman, you can use __all__ in __init__.py to
list the modules that should be imported if from packages import * is used. This is designed for this case.
The __init__.py has only this content:
__all__ = ['mod']
Now you can do this in main.py:
from packages import *
print mod.hello()
If you extend your __init__.py:
__all__ = ['mod']
from packages import *
You can do this in main.py:
import packages
print packages.mod.hello()
But if you remove the from packages import * from __init__.py:
__all__ = ['mod']
You will get an error:
AttributeError: 'module' object has no attribute 'mod'
because the __all__ is only used for the from packages import * case.
Now we are back to the __init__.py imports itself.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With