[Tutor] sending both a filename and an argument from the command line

Danny Yoo dyoo at hkn.eecs.berkeley.edu
Sat Nov 22 19:55:36 EST 2003


On Sun, 23 Nov 2003, Ben Vinger wrote:

> It seems I can send either a file(s), or arguments to a python script,
> but not both:
>
> I want to do:
>
> python ip.py myfile -i myargument


Hi Ben,

This should work, although probably not exactly as you might expect.


The 'optparse' module is responsible for parsing out the command line
arguments:

    http://www.python.org/doc/lib/module-optparse.html


When we say something like:

    python ip.py myfile -i myargument


Python itself has no idea how the words 'myfile', '-i', or 'myargument'
should be interpreted.  As far as Python is concerned, they are all only
strings:

###
[dyoo at tesuque dyoo]$ cat test_args.py
import sys
print sys.argv
[dyoo at tesuque dyoo]$ python test_args.py myfile -i myargument
['test_args.py', 'myfile', '-i', 'myargument']
###


The 'optparse' module takes sys.argv, and is the subsystem responsible for
interpreting each command line argument.

It appears that your program wants to use '-i' as an option.  'optparse'
provides tools for supporting options:

###
[dyoo at tesuque dyoo]$ cat test.py
#!/usr/local/bin/python2.3
"""A small script to test out optparse."""
import optparse
import sys
parser = optparse.OptionParser()
parser.add_option('-i')


options, argv = parser.parse_args(sys.argv)
print options
print "The rest of my argv variables are:", argv
###


Let's see how this works:

###
[dyoo at tesuque dyoo]$ ./test.py foobar -i myargument
<Values at 0x400e6ecc: {'i': 'myargument'}>
The rest of my argv variables are: ['./test.py', 'foobar']
###


Optparse doesn't interpret the command line arguments that it doesn't
understand, so it leaves those alone for us to handle.  If you want your
program to be able to handle something like:

    python ip.py - myargument

where '-' stands for standard in, then we can use 'optparse' in
combination with the 'fileinput' module.

    http://www.python.org/doc/lib/module-fileinput.html




For example, say that we want to write a program that uppercases (or
lowercases) whatever files we name on the command line.

###
#!/usr/local/bin/python2.3
"""Another small script to test out optparse."""

import optparse
import sys
import fileinput


def main():
    action, file = parseOptions()
    for line in file:
        sys.stdout.write(action(line))


def parseOptions():
    """Parses out command line options, and returns a
    line action and the files it should perform that action over."""
    parser = optparse.OptionParser()
    parser.add_option('-c', '--case', dest='case',
                      default='u',
                      help='[u/l] (u)ppercase or (l)owercase')
    options, argv = parser.parse_args()
    if options.case == 'u':
        return upperLine, fileinput.input(argv)
    else:
        return lowerLine, fileinput.input(argv)


def upperLine(line):
    return line.upper()


def lowerLine(line):
    return line.lower()


if __name__ == '__main__':
    main()
###



Here's an example of it in action:

###
[dyoo at tesuque dyoo]$ head test_optparse.py | ./test_optparse.py --case=u
#!/USR/LOCAL/BIN/PYTHON2.3
"""A SMALL SCRIPT TO TEST OUT OPTPARSE."""

IMPORT OPTPARSE
IMPORT SYS
IMPORT FILEINPUT


DEF MAIN():
    ACTION, FILE = PARSEOPTIONS()
[dyoo at tesuque dyoo]$ head test_optparse.py | ./test_optparse.py --case=l
#!/usr/local/bin/python2.3
"""a small script to test out optparse."""

import optparse
import sys
import fileinput


def main():
    action, file = parseoptions()
###




So 'optparse' and 'fileinput' should be powerful enough to handle the
command line arguments you want to parse.  If you have more questions,
please feel free to ask.

Good luck!




More information about the Tutor mailing list