Borrowing a simplified example at http://pythoncentral.io/how-to-create-a-python-package/
I have an analogous file structure as follows, where Mammals.py and Birds.py define classes with the same names:
Project/
Animals/
__init__.py
Mammals.py
Birds.py
When running an ipython interpreter within the Project/
directory and with __init__.py
being empty, the following works:
from Animals.Mammals import Mammals
x = Mammals()
x.printMammals()
I'd like to be able to write from Animals import Mammals
instead of from Animals.Mammals import Mammals
. And I believe the way to do that is to make the __init__.py
file contents the following:
from Mammals import Mammals
from Birds import Birds
However, when this is done, from within a similarly Project/
sourced ipython interpreter, the following input produces an error:
In [1]: from Animals import Mammals
---------------------------------------------------------------------------
ImportError Traceback (most recent call last)
<ipython-input-1-6d651848af9b> in <module>()
----> 1 from Animals import Mammals
/Users/username/Project/Animals/__init__.py in <module>()
----> 1 from Mammals import Mammals
2 from Birds import Birds
ImportError: No module named 'Mammals'
I feel that there is simple mistake that I am making, but can't find. Thanks for any help!
Put the following codes in the __init__.py
inside the Animals
directory.
Python 3.x :
from .Mammals import Mammals
from .Birds import Birds
On 2.x:
from __future__ import absolute_import
from .Mammals import Mammals
from .Birds import Birds
Explanation:
It can't find the module because it doesn't know what directory to search to find the files Mammals
and Birds
. You're assuming that the subfolder Animals
gets added to the python search path, but if you check sys.path
(executed from Projects/Animals/__init__.py
) you'll see that only the path to Project
is on the path. I'm not sure why the directory containing Project/Animals/__init__.py
is not searched, since that's the code being executed, but the error indicates this is the cause.
Putting a .
before the module name tells Python that the module you're loading is inside the current module's directory.
(Thanks to @SeanM's comment for explaining.)