如何检测并提高无命令行参数的错误

3

我有一个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](尽管可能做错了些什么)。这是所有解决方案中不断出现的错误(对类型和值之外的错误并不熟悉):
progname.py: error: argument -r/--rule: expected one argument

需要帮忙,请多关照。


没事了,问题已解决。 - user2998514
1个回答

1
p = argparse.ArgumentParser()
p.add_argument('-r', '--rule', nargs='?', default='string')
args = p.parse_args()
print args

nargs='?'表示如果没有参数调用,则会生成Namespace(rule='string')。使用-r,则argsNamespace(rule=None)。而-r something则生成Namespace(rule='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')

其他情况相同。
如果我删除defaultp.add_argument('-r','--rule',nargs ='?'),则无参数情况也会产生此自定义“错误消息”,因为默认值(在argparse中)为None
可以使用自定义typeaction添加自定义错误检查,但我认为在使用argparse后测试None更简单,更容易理解。
我建议将此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 有两个目的: - 如果给出了错误数量的参数字符串,则引发错误 - 将多个参数字符串分配给多个操作(由 add_argument 创建的东西)。
如果您有多个位置参数,分别取 1、2 和 * 参数,那么第二个目的尤为明显。这是 argparse 的一个关键新功能,至少相对于早期的 Python 解析器而言。虽然可以进行调整,但很难完全重新定义它。
如果参数允许,您可以使用 nargs='*' 而不是 '?',如果字符串的数量不是 '2'(或其他任何数量),则发出警告。

谢谢,这真让我烦恼。如果您已有一个具有必要数字值的narg语句,有没有解决方法? - user2998514
我已经添加了一个部分解决方案,重新定义了parser.error方法。 - hpaulj

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接