Python argparse 第二选择
Python argparse second choices
通过使用 Python argparse
模块,我目前有这个:
usage: prog [-h] (-a {opt1,opt2} | -b {opt3,opt4}) arg
.
但是,我想实现以下(选项-a
的第二组选择):
usage: prog [-h] (-a {opt1,opt2} {opt5,opt6} | -b {opt3,opt4}) arg
.
我不知道该怎么做。有帮助吗?
这个有效:
import argparse
class MultichoiceArgumentParser(argparse.ArgumentParser):
def _get_values(self, action, arg_strings):
if isinstance(action.nargs, int):
value = [self._get_value(action, v) for v in arg_strings]
for i, v in enumerate(value):
self._check_value(action, v, arg_num=i)
return value
else:
return super()._get_values(action, arg_strings)
def _check_value(self, action, value, arg_num=None):
# converted value must be one of the choices (if specified)
if action.choices is not None:
choices = action.choices
if isinstance(action, MultichoiceAction):
choices = choices[arg_num]
if value not in choices:
args = {'value': value,
'choices': ', '.join(map(repr, choices))}
msg = argparse._('invalid choice: %(value)r (choose from %(choices)s)')
raise argparse.ArgumentError(action, msg % args)
class MultichoiceAction(argparse._StoreAction):
pass
class MultichoiceFormatter(argparse.HelpFormatter):
def _metavar_formatter(self, action, default_metavar):
if action.choices is not None and isinstance(action, MultichoiceAction):
result = []
for choices in action.choices:
choice_strs = [str(choice) for choice in choices]
result.append('{%s}' % ','.join(choice_strs))
result = tuple(result)
return lambda x: result
else:
return super()._metavar_formatter(action, default_metavar)
要使用它:
parser = MultichoiceArgumentParser(formatter_class=MultichoiceFormatter)
parser.add_argument("-a", choices=["ABC", "XYZ"], nargs=2, action=MultichoiceAction)
print(parser.parse_args())
正在使用:
$ python d2.py -h
usage: d2.py [-h] [-a {A,B,C} {X,Y,Z}]
optional arguments:
-h, --help show this help message and exit
-a {A,B,C} {X,Y,Z}
$ python d2.py -a A X
Namespace(a=['A', 'X'])
$ python d2.py -a C Y
Namespace(a=['C', 'Y'])
$ python d2.py -a B Z
Namespace(a=['B', 'Z'])
$ python d2.py -a B B
usage: d2.py [-h] [-a {A,B,C} {X,Y,Z}]
d2.py: error: argument -a: invalid choice: 'B' (choose from 'X', 'Y', 'Z')
$ python d2.py -a X X
usage: d2.py [-h] [-a {A,B,C} {X,Y,Z}]
d2.py: error: argument -a: invalid choice: 'X' (choose from 'A', 'B', 'C')
$ python d2.py -a a b
usage: d2.py [-h] [-a {A,B,C} {X,Y,Z}]
d2.py: error: argument -a: invalid choice: 'a' (choose from 'A', 'B', 'C')
如上所示,您只需使用 MultichoiceArgumentParser
,将 MultichoiceFormatter
作为 formatter_class
参数。要使用多个不同的选择参数进行论证,choice
必须是序列的序列,与 nargs
的长度相同,并且 action
必须是 MultichoiceAction
。这与 store
的行为方式相同,因此其他行为将需要更多的子类化。
通过使用 Python argparse
模块,我目前有这个:
usage: prog [-h] (-a {opt1,opt2} | -b {opt3,opt4}) arg
.
但是,我想实现以下(选项-a
的第二组选择):
usage: prog [-h] (-a {opt1,opt2} {opt5,opt6} | -b {opt3,opt4}) arg
.
我不知道该怎么做。有帮助吗?
这个有效:
import argparse
class MultichoiceArgumentParser(argparse.ArgumentParser):
def _get_values(self, action, arg_strings):
if isinstance(action.nargs, int):
value = [self._get_value(action, v) for v in arg_strings]
for i, v in enumerate(value):
self._check_value(action, v, arg_num=i)
return value
else:
return super()._get_values(action, arg_strings)
def _check_value(self, action, value, arg_num=None):
# converted value must be one of the choices (if specified)
if action.choices is not None:
choices = action.choices
if isinstance(action, MultichoiceAction):
choices = choices[arg_num]
if value not in choices:
args = {'value': value,
'choices': ', '.join(map(repr, choices))}
msg = argparse._('invalid choice: %(value)r (choose from %(choices)s)')
raise argparse.ArgumentError(action, msg % args)
class MultichoiceAction(argparse._StoreAction):
pass
class MultichoiceFormatter(argparse.HelpFormatter):
def _metavar_formatter(self, action, default_metavar):
if action.choices is not None and isinstance(action, MultichoiceAction):
result = []
for choices in action.choices:
choice_strs = [str(choice) for choice in choices]
result.append('{%s}' % ','.join(choice_strs))
result = tuple(result)
return lambda x: result
else:
return super()._metavar_formatter(action, default_metavar)
要使用它:
parser = MultichoiceArgumentParser(formatter_class=MultichoiceFormatter)
parser.add_argument("-a", choices=["ABC", "XYZ"], nargs=2, action=MultichoiceAction)
print(parser.parse_args())
正在使用:
$ python d2.py -h
usage: d2.py [-h] [-a {A,B,C} {X,Y,Z}]
optional arguments:
-h, --help show this help message and exit
-a {A,B,C} {X,Y,Z}
$ python d2.py -a A X
Namespace(a=['A', 'X'])
$ python d2.py -a C Y
Namespace(a=['C', 'Y'])
$ python d2.py -a B Z
Namespace(a=['B', 'Z'])
$ python d2.py -a B B
usage: d2.py [-h] [-a {A,B,C} {X,Y,Z}]
d2.py: error: argument -a: invalid choice: 'B' (choose from 'X', 'Y', 'Z')
$ python d2.py -a X X
usage: d2.py [-h] [-a {A,B,C} {X,Y,Z}]
d2.py: error: argument -a: invalid choice: 'X' (choose from 'A', 'B', 'C')
$ python d2.py -a a b
usage: d2.py [-h] [-a {A,B,C} {X,Y,Z}]
d2.py: error: argument -a: invalid choice: 'a' (choose from 'A', 'B', 'C')
如上所示,您只需使用 MultichoiceArgumentParser
,将 MultichoiceFormatter
作为 formatter_class
参数。要使用多个不同的选择参数进行论证,choice
必须是序列的序列,与 nargs
的长度相同,并且 action
必须是 MultichoiceAction
。这与 store
的行为方式相同,因此其他行为将需要更多的子类化。