如何添加可选参数或一次参数?

时间:2013-08-31 04:26:43

标签: python argparse

如何添加一个可选的参数,不能多次指定?

有效:

$ ./my.py
$ ./my.py --arg MyArgValue

无效:

$ ./my.py --arg MyArgValue --arg ThisIsNotValid

如果我添加一个如下的参数:

parser.add_argument('--arg', type=str)

无效示例会生成字符串ThisIsNotValid。我希望解析器出错。

4 个答案:

答案 0 :(得分:3)

如果两次看到相同的参数,则创建一个引发异常的自定义操作。当解析器捕获异常时,它会打印用法和格式错误的错误消息。

import argparse

class Highlander(argparse.Action):
    def __call__(self, parser, namespace, values, option_string=None):
        if getattr(namespace, self.dest, None) is not None:
            raise argparse.ArgumentError(self, 'There can be only one.')
        setattr(namespace, self.dest, values)

parser = argparse.ArgumentParser()
parser.add_argument('-f', action=Highlander)
print (parser.parse_args('-f 1 -f 2'.split()))

答案 1 :(得分:1)

这感觉就像一个hacky解决方案,但会得到你想要的。使用append action

parser.add_argument('-arg', type=str, action='append')
args = parser.parse_args()
if len(args.arg) > 1:
    sys.exit("Only one argument is allowed for '-arg'")
elif len(args.arg) == 1: # elif is because it is valid for the length to be 0
    args.arg = args.arg[0]

追加操作将从命令行创建一个列表,该列表包含调用此参数的所有值。如果此列表的长度超过1,则出现错误。

这样您就可以从命令行获取值,如果有多个值,您可以将其作为错误捕获并通知用户。

答案 2 :(得分:0)

您可以使用它来获取出现的次数,如果多于一次则会产生错误。

  

'append' - 存储一个列表,并将每个参数值附加到列表中。这对于允许多次指定选项很有用。用法示例:

import argparse
import sys
parser = argparse.ArgumentParser()
parser.add_argument('-arg', type='str', action='append')
args = parser.parse_args()
if len(args.arg) > 1:
    sys.exit('Invalid')
MyArgValue = args.arg[0]

有关'追加'的文档可在此处找到,以获取更多详细信息:

http://docs.python.org/dev/library/argparse.html#action

不幸的是,argparse没有更简单的方法。这可能是因为这不是一个常见的用例。通常,此计数用于布尔情况,如详细模式。当你有附加字符串,比如包含路径的编译器等等时,它们通常都受到尊重。

也许,您也可以使用nargs并使用args.arg_name [0]并忽略其余部分。在这里,您可以找到nargs文档:

http://docs.python.org/dev/library/argparse.html#nargs

答案 3 :(得分:0)

我测试过使用mutually_exclusive_group的解决方案。我们的想法是定义一个包含--arg两次的组。解析器维护seen_non_default_actions列表,并在对新参数字符串执行操作之前检查独占组冲突。如果此列表中已存在--arg,则下一次调用将与其冲突,并引发错误。

这种方法存在一些问题。

1)无法将现有操作添加到新的mutual_exclusive_group。在https://stackoverflow.com/a/18555236/901925中,我举例说明了一个解决问题的方法。它还引用了一个提议的补丁,使这更容易。

2)当前parse_args将操作添加到seen_non_default_actions列表,然后检查冲突。这意味着第一个--arg将与自身发生冲突。解决方案是切换订单。首先检查冲突,然后将操作添加到列表中。

import my_argparse as argparse  # use a customized argparse
parser = argparse.ArgumentParser(prog="PROG",
    formatter_class=argparse.MultiGroupHelpFormatter)
# use a custom formatter than can handle overlapping groups

action = parser.add_argument('--arg', help='use this argument only once')
# define a group with two copies of this action as per patch issue10984
group = parser.add_mutually_exclusive_group(action, action)
args  = parser.parse_args()

使用各种参数调用时,生成:

$ python3 test.py -h
usage: PROG [-h] [--arg ARG | --arg ARG]

optional arguments:
  -h, --help  show this help message and exit
  --arg ARG   use this argument only once

$ python3 test.py --arg test
Namespace(arg='test')

$ python3 test.py --arg test --arg next
usage: PROG [-h] [--arg ARG | --arg ARG]
PROG: error: argument --arg: not allowed with argument --arg

我很奇怪,这是否是一种足够直观的说法,“只使用一次这个论点”。使用线[--arg ARG | --arg ARG]是否传达了这一点?错误消息argument --arg: not allowed with argument --arg是否足够清楚?