我试图为一个脚本创建一个可选参数,该参数可以不取值,也可以取2个值,不取其他值。你能用argparse完成这个吗?
# desired output:
# ./script.py -a --> works
# ./script.py -a val1 --> error
# ./script.py -a val1 val2 --> works
版本1--接受0或1值:
parser = argparse.ArgumentParser()
parser.add_argument("-a", "--action", nargs="?", const=True, action="store", help="do some action")
args = parser.parse_args()
# output:
# ./script.py -a --> works
# ./script.py -a val1 --> works
# ./script.py -a val1 val2 --> error
版本2-只接受2个值:
parser = argparse.ArgumentParser()
parser.add_argument("-a", "--action", nargs=2, action="store", help="do some action")
args = parser.parse_args()
# output:
# ./script.py -a --> error
# ./script.py -a val1 --> error
# ./script.py -a val1 val2 --> works
如何将这两个不同的版本组合在一起,使脚本接受参数的0或2个值,但在只有1个值时拒绝它?
您必须在这里进行自己的错误检查。接受0或更多值,并拒绝0或2以外的任何值:
parser = argparse.ArgumentParser()
parser.add_argument("-a", "--action", nargs='*', action="store", help="do some action")
args = parser.parse_args()
if args.action is not None and len(args.action) not in (0, 2):
parser.error('Either give no values for action, or two, not {}.'.format(len(args.action)))
注意,当未使用-a
开关时,args.action
设置为None
:
>>> import argparse
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument("-a", "--action", nargs='*', action="store", help="do some action")
_StoreAction(option_strings=['-a', '--action'], dest='action', nargs='*', const=None, default=None, type=None, choices=None, help='do some action', metavar=None)
>>> args = parser.parse_args([])
>>> args.action is None
True
>>> args = parser.parse_args(['-a'])
>>> args.action
[]
只需自己处理这种情况:
parser.add_argument("-a", "--action", nargs='*', action="store", help="do some action")
args = parser.parse_args()
if args.action is not None:
if len(args.action) not in (0, 2):
parser.error('Specify no or two actions')
# action was specified but either there were two actions or no action
else:
# action was not specified
当然,在这种情况下,您应该更新帮助文本,这样用户就有机会在遇到错误之前知道这一点。
让您的选项采用一个可选的逗号分隔字符串。您将使用自定义类型将该字符串转换为列表,并验证它是否正好有两个项。
def pair(value):
rv = value.split(',')
if len(rv) != 2:
raise argparse.ArgumentParser()
return rv
parser.add_argument("-a", "--action", nargs='?',
type=pair, metavar='val1,val2',
help="do some action")
print parser.parse_args()
然后你会像一样使用它
$ ./script.py -a
Namespace(action=None)
$ ./script.py -a val1,val2
Namespace(action=['val1','val2'])
$ ./script.py -a val1
usage: tmp.py [-h] [-a [ACTION]]
script.py: error: argument -a/--action: invalid pair value: 'val1'
$ ./script.py -a val1,val2,val3
usage: tmp.py [-h] [-a [ACTION]]
script.py: error: argument -a/--action: invalid pair value: 'val1,val2,val3'
您可以调整pair
的定义以使用不同的分隔符,并返回列表以外的内容(例如元组)。
metavar
提供了一个更好的指示,即action
的自变量是一对值,而不仅仅是一个值。
$ ./script.py -h
usage: script.py [-h] [-a [val1,val2]]
optional arguments:
-h, --help show this help message and exit
-a [val1,val2], --action [val1,val2]
do some action
所需参数:parser.add_argument("-a", "--action", nargs=2, action="store", help="do some action", required=False)