Python does not find module

Given the following python project created in PyDev:

β”œβ”€β”€ algorithms β”‚  β”œβ”€β”€ __init__.py β”‚  └── neighborhood β”‚  β”œβ”€β”€ __init__.py β”‚  β”œβ”€β”€ neighbor β”‚  β”‚  β”œβ”€β”€ connector.py β”‚  β”‚  β”œβ”€β”€ __init__.py β”‚  β”‚  β”œβ”€β”€ manager.py β”‚  β”‚  └── references.py β”‚  β”œβ”€β”€ neighborhood.py β”‚  β”œβ”€β”€ tests β”‚  β”‚  β”œβ”€β”€ fixtures β”‚  β”‚  β”‚  └── neighborhood β”‚  β”‚  β”œβ”€β”€ __init__.py β”‚  └── web β”‚  β”œβ”€β”€ __init__.py β”‚  └── service.py β”œβ”€β”€ configuration β”‚  β”œβ”€β”€ Config.py β”‚  └── __init__.py β”œβ”€β”€ __init__.py └── webtrack |- teste.py β”œβ”€β”€ .gitignore β”œβ”€β”€ __init__.py β”œβ”€β”€ manager   β”œβ”€β”€ Data.py   β”œβ”€β”€ ImportFile.py   └── __init__.py 

We tried without any success to import modules from one folder to another, for example:

 from algorithms.neighborhood.neighbor.connector import NeighborhoodConnector 

Which gives the result:

 Traceback (most recent call last): File "teste.py", line 49, in <module> from algorithms.neighborhood.neighbor.connector import NeighborhoodConnector ImportError: No module named algorithms.neighborhood.neighbor.connector 

We tried to add our path to the sys.path variable, but without success.

We also tried to use os.walk to insert all the paths into the PATH variable, but we get the same error, although we checked that PATH contains a path to search for modules.

We are using Python 2.7 for Linux Ubuntu 13.10.

Is there something we can do wrong?

Thanks in advance,

+7
python python-import
source share
4 answers

Obtaining import rights when running a script that lives inside a package is complex. You can read this (sadly delayed) section of PEP 395 for a description of several ways that do not work to run such a script.

Give the file system hierarchy, for example:

 top_level/ my_package/ __init__.py sub_package/ __init__.py module_a.py module_b.py sub_sub_package/ __init__.py module_c.py scripts/ __init__.py my_script.py script_subpackage/ __init__.py script_module.py 

There are only a few ways to make my_script.py work correctly.

  • The first would be to put the top_level folder in the PYTHONPATH environment variable or use the .pth file to achieve the same. Or, once the interpreter is running, paste this folder into sys.path (but it can get ugly).

    Note that you are adding top_level to the path, not my_package ! I suspect that this is what you have mixed up in your current attempts at this solution. Its very easy to make a mistake.

    Then absolute imports, such as import my_package.sub_package.module_a , will work mostly. (Just don't try to import package.scripts.my_script yourself while it works as the __main__ module, or you will get a strange duplicate copy of the module.)

    However, absolute imports will always be more verbose than relative imports, since you always need to specify the full path, even if you import a sibling module (or a "tribal" module, for example module_c from module_a ). With absolute imports, the way to get module_c always the big, ugly code language from my_package.sub_package.sub_sub_package import module_c , regardless of which module imports.

  • For this reason, the use of relative imports is often more elegant. Alas, it is difficult for them to work with the script. The only ways:

    • Run my_script from the my_script folder with the -m flag (e.g. python -m my_package.scripts.my_script ) and will never be by file name.

      It will not work if you are in a different folder, or if you use a different method to run the script (for example, pressing F5 in the IDE). This is somewhat inflexible, but there really is no way to make it easier (until PEP 395 is canceled and implemented).

    • Configure sys.path as for absolute imports (e.g. add top_level to PYTHONPATH or something else), then use PEP 366 __package__ to tell Python what the expected package of your script is. That is, in my_script.py you would like to add something like this above all your relative imports:

       if __name__ == "__main__" and __package__ is None: __package__ = "my_package.my_scripts" 

      This will require updating if you are reorganizing your file organization and moving the script to another package (but this probably works less than updating a large number of absolute imports).

    Once you have implemented one of these units, your import may become easier. Import module_c from module_a becomes from .sub_sub_package import module_c . In my_script relative imports, such as from ..subpackage import module_a , will work.

+3
source share

The way imports work is slightly different in Python 2 and 3. The first is Python 3 and a reasonable way (which you think is expected). In Python 3, all imports refer to folders in sys.path ( see here for more information on the module search path). By the way, Python does not use $PATH .

That way you can import anything from anywhere without worrying too much.

In Python 2, imports are relative, and sometimes absolute. The package document contains a sample layout and some import statements that may be useful to you.

The " Inside Party Links " section provides information on how to import between packages.

From all of the above, I think your sys.path incorrect. Make sure that the folder containing the algorithms (i.e. not the algorithms itself, but its parent) must be in sys.path

0
source share

Just set __pacage__ = None in each .py file. It will automatically configure the entire package hierarchy.

After that, you can freely use absolute module names for import.

from algorithms.neighborhood.neighbor.connector import NeighborhoodConnector

0
source share

I know this is an old post, but still I'm going to post my decision.

There was a similar problem. Just add the paths with the following line before importing the package:

 sys.path.append(os.path.join(os.path.dirname(__file__), '..')) from lib import create_graph 
0
source share

All Articles