Command-Line Arguments
The sys module is also where Python makes available the words typed on the command used to start a Python script. These words are usually referred to as command-line arguments, and show up in sys.argv, a built-in list of strings. C programmers may notice its similarity to the C "argv" array (an array of C strings). It's not much to look at interactively, because no command-line arguments are passed to start up Python in this mode:
>>> sys.argv ['']
To really see what arguments are about, we need to run a script from the shell command line. Example 2-2 shows an unreasonably simple one that just prints the argv list for inspection.
Example 2-2. PP2ESystem estargv.py
import sys print sys.argv
Running this script prints the command-line arguments list; note that the first item is always the name of the executed Python script file itself, no matter how the script was started (see Executable Scripts on Unix later in this chapter):
C:...PP2ESystem>python testargv.py ['testargv.py'] C:...PP2ESystem>python testargv.py spam eggs cheese ['testargv.py', 'spam', 'eggs', 'cheese'] C:...PP2ESystem>python testargv.py -i data.txt -o results.txt ['testargv.py', '-i', 'data.txt', '-o', 'results.txt']
The last command here illustrates a common convention. Much like function arguments, command-line options are sometimes passed by position, and sometimes by name using a "-name value" word pair. For instance, the pair -i data.txt means the -i option's value is data.txt (e.g., an input filename). Any words can be listed, but programs usually impose some sort of structure on them.
Command-line arguments play the same role in programs that function arguments do in functions: they are simply a way to pass information to a program that can vary per program run. Because they don't have to be hardcoded, they allow scripts to be more generally useful. For example, a file-processing script can use a command-line argument as the name of the file it should process; see the more.py script we met in Example 2-1 for a prime example. Other scripts might accept processing mode flags, Internet addresses, and so on.
Once you start using command-line arguments regularly, though, you'll probably find it inconvenient to keep writing code that fishes through the list looking for words. More typically, programs translate the arguments list on startup into structures more conveniently processed. Here's one way to do it: the script in Example 2-3 scans the argv list looking for -optionname optionvalue word pairs, and stuffs them into a dictionary by option name for easy retrieval.
Example 2-3. PP2ESystem estargv2.py
# collect command-line options in a dictionary def getopts(argv): opts = {} while argv: if argv[0][0] == '-': # find "-name value" pairs opts[argv[0]] = argv[1] # dict key is "-name" arg argv = argv[2:] else: argv = argv[1:] return opts if __name__ == '__main__': from sys import argv # example client code myargs = getopts(argv) if myargs.has_key('-i'): print myargs['-i'] print myargs
You might import and use such a function in all your command-line tools. When run by itself, this file just prints the formatted argument dictionary:
C:...PP2ESystem>python testargv2.py {} C:...PP2ESystem>python testargv2.py -i data.txt -o results.txt data.txt {'-o': 'results.txt', '-i': 'data.txt'}
Naturally, we could get much more sophisticated here in terms of argument patterns, error checking, and the like. We could also use standard and more advanced command-line processing tools in the Python library to parse arguments; see module getopt in the library manual for another option. In general, the more configurable your scripts, the more you must invest on command-line processing logic complexity.