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:
- Normalised paths are named path, (or dirpath or filepath if you want to be more specific)
- Directories and filenames without the path component are named filename or dirname
- Relative paths are named rpath
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.