Take the 2-minute tour ×
Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.

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
| README.md
| license.txt
| __root__.py
| special_resource.txt
| ./module
  |-- load.py

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'))
share|improve this question
    
You should choose an answer or provide more information. –  Joschua Jan 17 '13 at 15:41

2 Answers 2

up vote 1 down vote accepted

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.

share|improve this answer

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.

share|improve this answer
    
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

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.