使用argparse选择一个函数和供应选项

时间:2012-09-14 06:33:37

标签: python argparse

Most pythonic way of accepting arguments using optparse的接受答案中所述,我有一个程序,其中包含对字符串执行操作的函数。该程序使用argparse来检查字符串是按原样提供还是在文件中提供,并根据需要对输入进行按摩以将其传递给函数。

现在我想用我的函数的更高级版本扩展程序,但仍然保留基本版本以进行比较,有点像Use argparse to run 1 of 2 functions in my script。我认为我的情况不同的地方是,无论调用的函数如何,我都希望选择也传递我现有的输入标志。

只需向解析器添加一个新参数,并将我之前的代码嵌套在if / else中,检查该标志是不行的:它会抱怨错误的参数数量。我知道子命令,但我仍然是argparse的新手,似乎这对我想要的东西来说太过分了 - 但也许不是。

tl; dr:我需要选择两个函数之一和两个输入类型之一;两种输入类型都适用于这两种功能。谢谢你的帮助!

编辑添加代码:

p = argparse.ArgumentParser(description="program.py")
p.add_argument("-e", dest='extended')   #The new flag causing the trouble
p.add_argument("-s", dest="string")
p.add_argument("-f", dest="infile")

args = p.parse_args()

if args.extended:
    if args.infile:
        with open(args.infile,'r') as f:
            for line in enumerate(f.readlines()):
                print 'Input: ', line[1],    
                output = funcExtended(line[1])  #new and improved function
                print 'Extended output: ', output
    elif args.string:
        output = funcExtended(args.string)
        print output
    else:  #my future default option to grab strings from a database
        print 'This will soon work: extended'
else:   #I fully realize that I shouldn't have to essentially copy and paste here
    if args.infile:
        with open(args.infile,'r') as f:
            for line in enumerate(f.readlines()):
                print 'Input: ', line[1],    
                output = funcBasic(line[1])  #old and tired function
                print 'Basic output: ', output
    elif args.string:
        output = funcBasic(args.string)
        print output
    else:   #my future default option to grab strings from a database
        print 'This will soon work: basic'

这是一个命令行实用程序。发出

$ python program.py -s 'string'

返回格式正确的字符串,如前所述。但发布

$ python program.py -s 'string' -e

返回

program.py: error: argument -e: expected one argument

呼。再次感谢任何可以提供帮助的人!

1 个答案:

答案 0 :(得分:4)

如果使用

extended参数更改为布尔标志
p.add_argument("-e", dest='extended', action="store_true")

它将不再期待争论。然后,您可以使用

调用脚本
$ python program.py -e -s 'string'

最后,作为奖励,有一些想法可以减少您的代码冗余:

import argparse

def funcExtended(line):
   return " ".join(line)

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

p = argparse.ArgumentParser(description="program.py")
p.add_argument("-e", "--extended", dest="func", action="store_const", const=funcExtended, default=funcBasic)
p.add_argument("-s", "--string")
p.add_argument("-f", "--infile")

args = p.parse_args()

def readlines(args):
    if args.infile:
        with open(args.infile,'r') as f:
            for line in f:
                yield line.rstrip("\n")
    elif args.string:
        yield args.string
    else:  #my future default option to grab strings from a database
        print 'This will soon work: extended'

for line in readlines(args):
    print 'Input: ', line
    output = args.func(line)
    print "Output: ", output