Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting command line arguments as tuples in python

Here is an example of how I would like to call my script:

python script.py -f file1.txt "string1" "string2" -f file2.txt "string3" "string4"

Every file that goes as input will have 2 strings associated with that file. There can be any number of files.

To simplify, I am trying to get a print like this:

('file1.txt', 'string1', 'string2')
('file2.txt', 'string3', 'string4')

Here is what I have so far:

import sys, os, traceback, optparse
import time
import re
#from pexpect import run, spawn

def main ():
    global options, args

    print options.filename

    #for filename in options.filename:
    #  print filename
      #f = file(filename,'r')
      #for line in f:
      #  print line,
      #f.close()



if __name__ == '__main__':
    try:
        start_time = time.time()
        parser = optparse.OptionParser(formatter=optparse.TitledHelpFormatter(), usage=globals()['__doc__'], version='$Id$')
        parser.add_option ('-f', '--file', dest='filename', help='write report to FILE', metavar='FILE', nargs=3)
        parser.add_option ('-v', '--verbose', action='store_true', default=False, help='verbose output')
        (options, args) = parser.parse_args()
        #if len(args) < 1:
        #    parser.error ('missing argument')
        if options.verbose: print time.asctime()
        main()
        if options.verbose: print time.asctime()
        if options.verbose: print 'TOTAL TIME IN MINUTES:',
        if options.verbose: print (time.time() - start_time) / 60.0
        sys.exit(0)
    except KeyboardInterrupt, e: # Ctrl-C
        raise e
    except SystemExit, e: # sys.exit()
        raise e
    except Exception, e:
        print 'ERROR, UNEXPECTED EXCEPTION'
        print str(e)
        traceback.print_exc()
        os._exit(1)

With the above script, I get only the second file and related strings:

('file2.txt', 'string3', 'string4')
like image 715
bits Avatar asked Mar 21 '11 00:03

bits


People also ask

Can a tuple be an argument in Python?

A tuple can also be passed as a single argument to the function.

Can Python take command-line arguments?

Python exposes a mechanism to capture and extract your Python command line arguments. These values can be used to modify the behavior of a program. For example, if your program processes data read from a file, then you can pass the name of the file to your program, rather than hard-coding the value in your source code.

How do you capture an argument in Python?

To access command-line arguments from within a Python program, first import the sys package. You can then refer to the full set of command-line arguments, including the function name itself, by referring to a list named argv. In either case, argv refers to a list of command-line arguments, all stored as strings.


2 Answers

I think you want to use the action=append argument of the add_argument method

import argparse

parser= argparse.ArgumentParser()
parser.add_argument ('-f', '--file', nargs=3, action='append')

files = parser.parse_args('-f file1 string1 string2 -f file2 string3 string4 -f file3 string5 string6'.split()).file

for f in files:
    print tuple(f)

gives you:

('file1', 'string1', 'string2')
('file2', 'string3', 'string4')
('file3', 'string5', 'string6')

Testing on cli:

with:

import argparse

parser= argparse.ArgumentParser(prog='Test', usage='%(prog)s -f Filename Option1 Option2 ')
parser.add_argument ('-f', '--file', nargs=3, action='append')

files = parser.parse_args().file

for f in files:
    print tuple(f)

results:

python test.py -f file1 "foo bar" "baz" -f file2 foo bar
('file1', 'foo bar', 'baz')
('file2', 'foo', 'bar')

python test.py -f file1 "foo bar" "string2" -f file2 foo bar -f file3 "foo" "bar"
('file1', 'foo bar', 'string2')
('file2', 'foo', 'bar')
('file3', 'foo', 'bar')

python test.py -f file1 "foo bar"
usage: Test -f Filename Option1 Option2
Test: error: argument -f/--file: expected 3 argument(s)
like image 189
dting Avatar answered Oct 29 '22 21:10

dting


argparse supports the notion of accumulators, which allow you to specify the same option more than once, which is probably more like what you want than anything optparse supports (your particular problem is that optparse doesn't know what to do with an argument specified multiple times, so it's "last one wins" at the command line). argparse is included in Python 2.7 and 3.2, but you should be able to download it for anything 2.6.x or later.

like image 32
Nick Bastin Avatar answered Oct 29 '22 23:10

Nick Bastin