You are here: Home > Dive Into Python > Functional Programming > Finding the path | << >> | ||||
Dive Into PythonPython from novice to pro |
When running Python scripts from the command line, it is sometimes useful to know where the currently running script is located on disk.
This is one of those obscure little tricks that is virtually impossible to figure out on your own, but simple to remember once you see it. The key to it is sys.argv. As you saw in Chapter 9, XML Processing, this is a list that holds the list of command-line arguments. However, it also holds the name of the running script, exactly as it was called from the command line, and this is enough information to determine its location.
If you have not already done so, you can download this and other examples used in this book.
import sys, os print 'sys.argv[0] =', sys.argv[0] pathname = os.path.dirname(sys.argv[0]) print 'path =', pathname print 'full path =', os.path.abspath(pathname)
os.path.abspath deserves further explanation. It is very flexible; it can take any kind of pathname.
>>> import os >>> os.getcwd() /home/you >>> os.path.abspath('') /home/you >>> os.path.abspath('.ssh') /home/you/.ssh >>> os.path.abspath('/home/you/.ssh') /home/you/.ssh >>> os.path.abspath('.ssh/../foo/') /home/you/foo
The pathnames and filenames you pass to os.path.abspath do not need to exist. |
os.path.abspath not only constructs full path names, it also normalizes them. That means that if you are in the /usr/ directory, os.path.abspath('bin/../local/bin') will return /usr/local/bin. It normalizes the path by making it as simple as possible. If you just want to normalize a pathname like this without turning it into a full pathname, use os.path.normpath instead. |
[you@localhost py]$ python /home/you/diveintopython/common/py/fullpath.py sys.argv[0] = /home/you/diveintopython/common/py/fullpath.py path = /home/you/diveintopython/common/py full path = /home/you/diveintopython/common/py [you@localhost diveintopython]$ python common/py/fullpath.py sys.argv[0] = common/py/fullpath.py path = common/py full path = /home/you/diveintopython/common/py [you@localhost diveintopython]$ cd common/py [you@localhost py]$ python fullpath.py sys.argv[0] = fullpath.py path = full path = /home/you/diveintopython/common/py
Like the other functions in the os and os.path modules, os.path.abspath is cross-platform. Your results will look slightly different than my examples if you're running on Windows (which uses backslash as a path separator) or Mac OS (which uses colons), but they'll still work. That's the whole point of the os module. |
Addendum. One reader was dissatisfied with this solution, and wanted to be able to run all the unit tests in the current directory, not the directory where regression.py is located. He suggests this approach instead:
import sys, os, re, unittest def regressionTest(): path = os.getcwd() sys.path.append(path) files = os.listdir(path)
This technique will allow you to re-use this regression.py script on multiple projects. Just put the script in a common directory, then change to the project's directory before running it. All of that project's unit tests will be found and tested, instead of the unit tests in the common directory where regression.py is located.
<< Functional Programming |
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | |
Filtering lists revisited >> |