views:

762

answers:

4

We are working with a code repository which is deployed both to windows and linux, sometimes on different directories. How should one of the modules inside the project refer to one of the non-python resources in the project (CSV file, etc.)? If we do something like

thefile=open('test.csv')

or

thefile=open('../somedirectory/test.csv')

It will work only when the script is run from one specific directory, or a subset of the directories. What I would like to do is something like:

path=getBasePathOfProject()+'/somedirectory/test.csv'
thefile=open(path)

Is this the right way? Is it possible? Thanks

+1  A: 

Try to use a filename relative to the current files path. Example for './my_file':

fn = os.path.join(os.path.dirname(__file__), 'my_file')
Chris089
I think this solution will only work if the resource is in the same directory of the python file, or in a sub directory of it.How do you solve it when you have the following tree structure:/Project_Root_dir /python_files_dir /Some more subdirs here py_file.py /resources /some subdirs here resource_file.csv
noam
Sorry, the file tree got garbled on that last message... second try:you have your file at /Project_Root_dir/python_files_dir/some_subdirs/py_file.py and you have your resource file at /Project_Root_dir/resources/some_subdirs/resource_file.csv
noam
You should be able to get to the parent directory using join(foo, '..'). So from /root/python_files/module/myfile, use os.path.join(os.path.dirname(`__file__`), '..', '..', 'resources')
Chris089
A: 

You can use the build in file variable. It contains the path of the current file. I would implement getBaseOfProject in a module in the root of your project. There I would get the path part of file and would return that. This method can then be used everywhere in your project.

Achim
A: 
import os
cwd = os.getcwd()
path = os.path.join(cwd, "my_file")
f = open(path)

You also try to normalize your cwd using os.path.abspath(os.getcwd()). More info here.

gavoja
A: 

I often use something similar to this:

import os
DATA_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), 'datadir'))

# if you have more paths to set, you might want to shorten this as
here = lambda x: os.path.abspath(os.path.join(os.path.dirname(__file__), x))
DATA_DIR = here('datadir') 

pathjoin = os.path.join
# ...
# later in script
for fn in os.listdir(DATA_DIR):
    f = open(pathjoin(DATA_DIR, fn))
    # ...

The variable

__file__

holds the file name of the script you write that code in, so you can make paths relative to script, but still written with absolute paths. It works quite well for several reasons:

  • path is absolute, but still relative
  • the project can still be deployed in a relative container

But you need to watch for platform compatibility - Windows' os.pathsep is different than UNIX.