MisterButter
MisterButter

Reputation: 797

How to import module in different path without appending path to module?

Given below repo structure


cli_stats/      
|__ __init__.py 
|__ README.md   
|__ docs/   
|     |__ docs
|__ cli_stats/  
|     |__  cli_stats.py
|     |__  league_season_init.pickle (generated from setup.py)
|__ pickle/ 
|     |__  __init__.py
|     |__  setup.py
|     |__  get_id/
|     |       |__ __init__.py
|     |       |__ get_id.py
|     |__ get_stats/
|     |       |__ __init__.py
|     |       |__ get_stats.py
|     |__ api_scraper/
|         |__ __init__.py
|         |__ api_scraper.py
|         |__  check_api.py
|       
|__ directory/  
|    |__ __init__.py
|    |__ directory.py
|__clean_stats/ 
     |__ __init__.py
     |__ clean_stats.py

How can I import for example import directory.py to clean_stats.py without inserting the path to directory.py to clean_stats.py directly? What I'm doing now:

sys.path.insert(0, '../directory')
from directory import Directory

What I would like to do:

from directory import Directory

Is there someway to utilise the __init__.py to be able to do these kind of imports?

Upvotes: 0

Views: 988

Answers (1)

progmatico
progmatico

Reputation: 4964

In clean_stats.py:

from ..directory import Directory

For Directory to be recognized, instead of having to write

from ..directory.directory import Directory you will need to put in directory/__init__.py:

from . import Directory

Finally, all relative imports work fine when you import your package from one upper level, that is, from a script in the parent folder of cli_stats.

If you start execution from some other entry point inside your package, there are always imports that will fail, unless you fix the relative path from the point of view of the starting script. Problem is, if you do that, you fix one place and others will become wrong, always. So make your import package to be imported and used from outside, not to run directly from an inside script. Even if you write absolute import paths starting with the package name everywhere, this issue persists because the inner starting point cannot see the outer subpackages.

Note that there are other options like appending sys.path as you did, defining PYTHONPATH, or having packages installed in the system or in a virtualenv via pip, pip -e and so on. But all this options are usually for additional libraries you depend on, not for your package internals.

Upvotes: 1

Related Questions