# Accessing the contents of a project's root directory in Python

This morning I was trying to find a good way of using os.path to load the content of a text file into memory, which exists in the root directory of my current project.

This approach strikes me as a bit hackneyed, but after some thought it was exactly what I was about to do, except with os.path.normpath(os.path.join(__file__, '..', '..'))

These relative operations on the path to navigate to a static root directory are brittle.

Now, if my project layout changes, these associations to the (former) root directory change with it. I wish I could assign the path to find a target, or a destination, instead of following a sequence of navigation operations.

I was thinking of making a special __root__.py file. Does this look familiar to anyone, or know of a better implementation?

my_project
|
| __init__.py
| __root__.py
| special_resource.txt
| ./module


Here is how it is implemented:

"""__root__.py"""
import os
def path():
return os.path.dirname(__file__)


And here is how it could be used:

"""load.py"""
import __root__
def resource():
return open(os.path.join(__root__.path(), 'special_resource.txt'))

-
You should choose an answer or provide more information. – Joschua Jan 17 '13 at 15:41

your approach seems ok, but as it is not a common problem/solution, you should document what your __root__.py file is doing.

One thing: you should not use double leading and trailing underscores, see pep8

double_leading_and_trailing_underscore: "magic" objects or attributes that live in user-controlled namespaces. E.g. __init__, __import__ or __file__. Never invent such names; only use them as documented.

-

I never heard of __root__.py and don't think that is a good idea.

Instead create a files.py in a utils module:

MAIN_DIRECTORY = dirname(dirname(__file__))
def get_full_path(*path):
return join(MAIN_DIRECTORY, *path)


You can then import this function from your main.py:

from utils.files import get_full_path

path_to_map = get_full_path('res', 'map.png')


So my project directory tree looks like this:

project_main_folder/
utils/
__init__.py (empty)
files.py
main.py


When you import a module the Python interpreter searches if there's a built-in module with that name (that's why your module name should be different or you should use relative imports). If it hasn't found a module with that name it will (among others in sys.path) search in the directory containing your script. You can find further information in the documentation.

-
But how do you import main without knowing where the main directory is already? – raylu Jan 15 '13 at 3:17
I modified my answer to include the import line and also put the function in the module utils.files. – Joschua Jan 15 '13 at 16:28
My question remains the same: how do you import utils.files without knowing where utils is? – raylu Jan 16 '13 at 1:23
When you put the code that imports utils.files in main.py Python will automatically figure it out. I added further information to my answer. – Joschua Jan 16 '13 at 15:54
Oh. What if I'm in dir1/module1.py and I want to import dir2.module2? – raylu Jan 16 '13 at 20:08