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!
This is caused by the fact that the version of Python you're running your script with is not configured to search for modules where you've installed them. This happens when you use the wrong installation of pip to install packages.
The __init__.py file makes Python treat directories containing it as modules. Furthermore, this is the first file to be loaded in a module, so you can use it to execute code that you want to run each time a module is loaded, or specify the submodules to be exported.
Leaving an __init__.py file empty is considered normal and even a good practice, if the package's modules and sub-packages do not need to share any code.
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.)
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