如何在没有命令行参数的情况下检查并引发错误

时间:2013-11-29 01:10:59

标签: python parsing dictionary import argparse

我有一个argparsing程序:

import argparse

def main():
    p = argparse.ArgumentParser()
    help_str = {'rule': 'Blah blah blah and stuff.'}
    p.add_argument('-r', '--rule', action="store", type=str, dest='rule', help=help_str['rule'])
    p.set_defaults(rule='string')
    args = p.parse_args()

因此,我的命令行输入:

username@compname:~$python progname.py -r/--rule 'something'

我想知道如何输入:

username@compname:~$python progname.py -r/--rule

并出现我自己的错误消息:

print '\n    Error: no input value for rule:'
print '    resetting rule to default value.'
args.rule = 'string'

之后,规则值应打印为'string'

我对Python只有一点点流利,对不起。我尝试过使用try / except块甚至sys.argv [2](虽然我可能做错了。)这是错误,不断出现我的所有解决方案(不太熟悉Type和Value之外的错误) :

progname.py: error: argument -r/--rule: expected one argument

任何帮助表示感谢。

1 个答案:

答案 0 :(得分:1)

p = argparse.ArgumentParser()
p.add_argument('-r', '--rule', nargs='?', default='string')
args = p.parse_args()
print args
如果在没有参数的情况下调用,{p> nargs='?'会生成Namespace(rule='string')。使用-r时,args为Namespace(rule=None)。并Namespace(rule='something')-r something

让我们添加几行代码

if args.rule is None:
    print '\n    Error: no input value for rule:'
    print '    resetting rule to default value.'
    args.rule = 'string'
print args

现在带'-r'(或--rule)的输出是:

Namespace(rule=None)

    Error: no input value for rule:
    resetting rule to default value.
Namespace(rule='string')

其他案例是相同的。

如果我放弃default; p.add_argument('-r', '--rule', nargs='?'),无参数情况也会产生此自定义“错误消息”,因为默认值(在argparse中)为None

可以使用自定义typeaction添加自定义错误检查,但我认为使用None后对argparse的测试更简单,更易于理解。

我建议将此error message更改为warning。错误通常会终止程序;警告打印消息并继续。


这是nargs=2(或其他固定的东西)的解决方案。这不是一个微不足道的变化,因为它涉及重新定义error方法(记录在argparse文档的末尾附近),然后捕获它产生的错误。 error方法无法访问命名空间(args),也无法继续parse_args。因此,如果rule参数存在问题,它就无法处理任何其他参数。

class MyParser(argparse.ArgumentParser):
    def error(self, message):
        if 'rule' in message:
            message = 'wrong number of input values for rule'
            raise argparse.ArgumentError(None,message)
            # cannot access namespace or continue parsing
        else:
            super(MyParser, self).error(message)

p = MyParser()
p.add_argument('-r', '--rule', nargs=2)
try:
    args = p.parse_args()
except argparse.ArgumentError as e:
    print e
    args = argparse.Namespace(rule='default')
    # create a namespace with this default value
print args

请注意,nargs有两个目的: - 如果给出错误数量的参数字符串,则引发错误 - 在多个Actions(由add_argument创建的东西)中分配多个参数字符串。

如果你有几个位置,分别取1,2和*参数,那么第二个就特别明显了。它是argparse的一个关键新颖特性,至少相对于早期的Python解析器而言。虽然可以调整它,但很难完全重新定义它。

如果参数允许,您可以使用nargs='*'而不是'?',如果字符串数不是'2'(或其他),则发出警告。