如何添加一个可选的参数,不能多次指定?
有效:
$ ./my.py
$ ./my.py --arg MyArgValue
无效:
$ ./my.py --arg MyArgValue --arg ThisIsNotValid
如果我添加一个如下的参数:
parser.add_argument('--arg', type=str)
无效示例会生成字符串ThisIsNotValid
。我希望解析器出错。
答案 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
文档:
答案 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
是否足够清楚?