tags:

views:

119

answers:

2

What is the best way to find a file "upwardly" in Python? (Ideally it would work on Windows too). E.g.,

>>> os.makedirs('/tmp/foo/bar/baz/qux')
>>> open('/tmp/foo/findme.txt', 'w').close()
>>> os.chdir('/tmp/foo/bar/baz/qux')
>>> findup('findme.txt')
'/tmp/foo/findme.txt'

As far as I can tell, there isn't anything in the Python standard library (although I'd love to be proven wrong). Also, googling around didn't turn up much that's definitive; I'm wondering if there's something out there that "everyone" uses.

+1  A: 

The module os.path has what you need, in particular: abspath() (if the path is not absolute), dirname(), isfile(), and join().

dir = os.path.curdir()
filename = None
while True:
    filename = os.path.join(dir, 'filename')
    if os.path.isfile(filename):
        break
    updir = os.path.dirname(dir)
    if updir == dir:
        filename = None
        break
    dir = updir

Edit: change posixpath to os.path so that this works on Windows.

Edit x2: add code.

Dave
os.isfile() is not a function. Try os.path.isfile().
nosklo
+3  A: 
import os

def findup(filename):
    drive, thisdir = os.path.splitdrive(os.getcwd())
    while True:
        fullpath = os.path.join(drive, thisdir, filename)
        if os.path.isfile(fullpath):
            return fullpath
        if thisdir == os.path.sep: #root dir
            raise LookupError('file not found: %r' % filename)
        thisdir = os.path.dirname(thisdir)

os.makedirs('/tmp/foo/bar/baz/qux')
open('/tmp/foo/findme.txt', 'w').close()
os.chdir('/tmp/foo/bar/baz/qux')
print findup('findme.txt')

Prints:

/tmp/foo/findme.txt

Also works on Windows. Probably will work on any platform.

nosklo