Short answer
So what does the from packages import * really mean inside that __init__.py?
The __init__.py imports itself.
Explanation
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.