Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

__init__.py can't find local modules

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!

like image 563
Darren McAffee Avatar asked Jan 12 '16 20:01

Darren McAffee


People also ask

Why can't Python find my module?

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.

What is the __ init __ py module?

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.

Should __ init __ py be empty?

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.


1 Answers

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.)

like image 190
masnun Avatar answered Oct 21 '22 10:10

masnun