0

Let's say that I have a folder, x, containing the two folders foo and bar. Inside foo I have a Python script and inside bar, I have my data (let's say a couple of .txt files). Now, from within my script, I would like to access my data. I could simply use this command and call it a day:

fileList = glob.glob('/absolute/path/to/bar/*.txt')

However, using this method, my script would break if I moved my x folder.

What's the easiest way to specify the path in a relative manner that allows me to move around the parent folder, x, freely?

Speldosa
  • 1,560
  • 3
  • 17
  • 34

2 Answers2

4

../ specifies your parent directory, so ../bar/*.txt.

Like John Gordon said, this works assuming you're inside x/foo/ and running the script from there.

If you're not executing the script from its own directory, you'll need to find out where your script currently is. This is not trivial. felipsmartins' solution of using os.path.dirname(os.path.dirname(__file__)) is generally fine, but doesn't work in all cases. See e.g. here: How to properly determine current script directory in Python?

Community
  • 1
  • 1
Marco Tompitak
  • 608
  • 1
  • 5
  • 12
  • 2
    ... assuming the user is sitting inside the `foo` folder when they run the script. – John Gordon Oct 30 '15 at 17:33
  • This is the answer I thought you were looking for. Another approach would be to store the directories in a config file and use [ConfigParser][1]to read them in at run time. [1]: https://docs.python.org/2/library/configparser.html – RobertB Oct 30 '15 at 17:37
  • @MarcoTompitak Oh, no... My solution works well in all cases. – felipsmartins Oct 31 '15 at 15:06
  • The link I provided highlights some problems with the `__file__` method. Granted, it works in most cases, I just wanted to add the caveat that in some scenarios it does not. – Marco Tompitak Oct 31 '15 at 15:10
2

I think __file__ is a nice approach:

import glob
import os

# "x" folder
base_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))   
files = glob.glob(os.path.join(base_dir, 'bar', '*.txt'))

Working from top directory is a lot easier. Django and other frameworks does it too.
Also, it solves issues when invoking script from command line and from different locations.

Another approch is usging os.chdir(), changing working directory:

import glob
import os

# same that: cd /absolute path/for/x folder
os.chdir(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

files = glob.glob(os.path.join('bar', '*.txt'))

Zend Framework (PHP) uses the above approach in bootstrap file.

Both solutions works very well for all cases.

felipsmartins
  • 11,616
  • 3
  • 40
  • 50
  • So the assumption with this answer is that the directories are always in the same position relative to the program file, it is just the base directory that moves. In that case, I like this idea. – RobertB Oct 30 '15 at 17:44