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