James Gardner: Home > Blog > 2009 > Dealing with Paths

Dealing with Paths

Posted:2009-04-25 14:07
Tags:Python

One issue I've come across is how to deal with paths. My conclusion is that all input from the command line which takes the form of a filename or a directory should immediately be converted into a normalised, absolute path like this:

import os.path
os.path.normpath(os.path.abspath(path))

This makes paths easier to work with in the application because the same physical path will always be represented by the same string. I've written a function called uniform_path() which does this. Variables are named according to this convention:

Relative Paths

Python 2.6 has an implementation for calculating relative paths called os.path.relpath(). I use the following code to make a relpath() function available to the module globally, regardless of whether the user is using Python 2.6 or an earlier version. This version only works on Posix platforms, because it uses posixpath.

import posixpath
# relpath import (available in Python 2.6 and above)
try:
    relpath = posixpath.relpath
except AttributeError:

    from posixpath import curdir, sep, pardir, join

    def relpath(path, start=curdir):
        """Return a relative version of a path"""

        if not path:
            raise ValueError("no path specified")

        start_list = posixpath.abspath(start).split(sep)
        path_list = posixpath.abspath(path).split(sep)

        # Work out how much of the filepath is shared by start and path.
        i = len(posixpath.commonprefix([start_list, path_list]))

        rel_list = [pardir] * (len(start_list)-i) + path_list[i:]
        if not rel_list:
            return curdir
        return join(*rel_list)

Incidentally, os.path is just an alias which defaults to the correct module for your platform. On Linux it uses the posixpath module from the standard library.

(view source)

James Gardner: Home > Blog > 2009 > Dealing with Paths