5

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

有效的:

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

无效的:

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

如果我添加如下参数:

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

无效示例产生一个字符串ThisIsNotValid。我预计会出现解析器错误。

4

4 回答 4

4

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

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()))
于 2013-08-31T06:16:01.000 回答
1

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

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,则出现错误。

通过这种方式,您可以从命令行获取值,如果有多个值,您可以将其视为错误并通知用户。

于 2013-08-31T04:47:45.370 回答
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

于 2013-08-31T04:43:44.527 回答
0

我测试了一个使用mutually_exclusive_group. 这个想法是定义一个包含--arg两次的组。解析器维护一个seen_non_default_actions列表,并在对新参数字符串采取操作之前检查该列表是否存在排他性组冲突。如果--arg此列表中已经存在,则下一次调用将与它发生冲突,并引发错误。

这种方法有几个问题。

1) 现有操作不能添加到新的互斥组。在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足够清楚?

于 2013-09-02T01:24:45.513 回答