8

I have a file structure like this:

data
   mydata.xls
scripts
   myscript.py

From within myscript.py, how can I get the filepath of mydata.xls?

I need to pass it to xlrd:

book = xlrd.open_workbook(filename)

and relative filepaths like '../data/mydata.xls' don't seem to work.

AP257
  • 89,519
  • 86
  • 202
  • 261

4 Answers4

11

You can use os.path.abspath(<relpath>) to get an absolute path from a relative one.

vinko@parrot:~/p/f$ more a.py
import os
print os.path.abspath('../g/a')

vinko@parrot:~/p/f$ python a.py
/home/vinko/p/g/a

The dir structure:

vinko@parrot:~/p$ tree
.
|-- f
|   `-- a.py
`-- g
    `-- a

2 directories, 2 files
Vinko Vrsalovic
  • 330,807
  • 53
  • 334
  • 373
10

If you want to made it independent from your current directory try

os.path.join(os.path.dirname(__file__), '../data/mydata.xls')

The special variable __file__ contains a relative path to the script in which it's used. Keep in mind that __file__ is undefined when using the REPL interpreter.

Adam Byrtek
  • 12,011
  • 2
  • 32
  • 32
  • 1
    +1 For a solution that will work even when the script is invoked from some other directory. – FMc Sep 21 '10 at 09:35
  • 1
    Doesn't work: produces: IOError: [Errno 2] No such file or directory: '/my/file/path/load/../data/mydata.xls' – AP257 Sep 21 '10 at 09:42
  • @AP257: Is the path in the error message correct or not? You can translate it to an absolute path using `os.path.abspath`, but this shouldn't make a difference. – Adam Byrtek Sep 21 '10 at 17:26
  • Without wraping that into `os.path.abspath` that will not work. – Eduardo Mar 24 '18 at 16:08
4
import os
directory = os.path.dirname(os.getcwd())
final = os.path.join(directory, 'data', 'mydata.xls')

or simply

os.path.abspath('../data/mydata.xls')
Leniel Maccaferri
  • 100,159
  • 46
  • 371
  • 480
dheerosaur
  • 14,736
  • 6
  • 30
  • 31
-1

From you comments, it seems that book = xlrd.open_workbook(filename) doesn't like relative path. You can create a path relative to the current file __file__ and then take the absolute path that will remove the relative portions (..)

import os

filename = os.path.join(os.path.dirname(__file__), '../data/mydata.xls')
book = xlrd.open_workbook(os.path.abspath(filename))
Rod
  • 52,748
  • 3
  • 38
  • 55
  • -1 It seems that you don't understand that a ".." relative path is relative to the *current working directory* whereas the OP wants a path that's relative to his *script directory*; it's nothing at all to do with `xlrd`. Secondly `__file__` is the path to the *currently executing file*, which is no use if the OP wants to put his code in an imported utility module. – John Machin Sep 25 '10 at 22:59
  • @John I failed to see how my answer is any different from the previous answers except that I remove the path "relative" parts. I am simply mixing answers from Vinko and Adam. Is it my explanation that granted me a down vote? The OP does not talk about a relative directory but from his myscript.py file. I agree that using __file__ is of no use if it is intented to be used in a module but the OP did not specify this. – Rod Sep 26 '10 at 00:37
  • Other answers don't include your fatuous first sentence. xlrd.open_workbook() merely passes the filename unmodified to the built-in 'open()' -- "doesn't like relative path" is a nonsense. – John Machin Sep 26 '10 at 04:20