如何将 ArgumentParser 与两个都接受 nargs='*' 的短可选参数一起使用
How to use ArgumentParser with two short optional arguments which both accept nargs='*'
我正在尝试为我的项目配备从 cli 控制的日志记录功能。为此,我使用 ArgumentParser 来解析标志“-v”以进行冗长和“-d”以进行调试。应该可以在它们后面指定可选的名称空间。请参阅下面的代码段。问题在最后。
parser = argparse.ArgumentParser()
parser.add_argument('-v', '--verbose',
dest='verbose',
metavar='namespace',
nargs='*',
help='Sets the logging level to INFO.')
parser.add_argument('-d', '--debug,
dest='debug',
metavar='namespace',
nargs='*',
help='Sets the logging level to DEBUG.')
args = parser.parse_args()
if args.verbose:
print('verbose: ', args.verbose)
if args.debug:
print('debug: ', args.debug)
因此帮助用法类似于:
optional arguments:
-v [namespace [namespace ...]]
-d [namespace [namespace ...]]
我将它与类似下面的代码片段的内容一起使用。这只是您了解我的意图的背景信息。
logging_level = logging.INFO # just as example for -v
if not namespace:
logger = logging.getLogger()
logger.setLevel(logging_level)
else:
for n in namespace:
child_logger = logger.getChild(f'{root_module_name}.{namespace}')
child_logger.setLevel(logging_level)
问题
1.) 如果我调用 python my_module.py -v A -d B
输出会像预期的那样:
verbose: ['A']
debug: ['B']
2.) 如果我调用 python my_module.py -v -d
输出会像预期的那样:
verbose: []
debug: []
3.) 但是如果我调用 python my_module.py -vd
输出看起来像:
verbose: ['d']
debug: None
我要实现的是:
verbose: []
debug: []
4.) 如果我称它为 python my_module.py -vd B
会变得更糟
error: unrecognized arguments: B
我要实现的是:
verbose: []
debug: ['B']
问题 是如何实现我想要的行为 3.) 和 4.)?
我知道我可以使用符合我要求的 python my_module.py --verbose --debug B
绕过这个问题。但这不是我要问的。
最简单的解决方案是不使用“-vd”输入。
'-vd' 被解析为 `-v d'。由于“-v”是一个带参数的短选项,它将以下字符串解释为一个值,而不是另一个标志。
您会期望“-vb”产生 ['b']
,对吧?为什么它对待“-vd”有什么不同?
人们更经常抱怨“-v -d”未能将“-d”视为“-v”的参数(通常是“-v”需要一个参数)。
'-vd' 将被解析为 '-v -d' 如果 '-v' 没有参数,例如如果它是 'store_true' (nargs=0
).
https://docs.python.org/3/library/argparse.html#option-value-syntax
For short options (options only one character long), the option and its value can be concatenated:
Several short options can be joined together, using only a single - prefix, as long as only the last option (or none of them) requires a value:
我正在尝试为我的项目配备从 cli 控制的日志记录功能。为此,我使用 ArgumentParser 来解析标志“-v”以进行冗长和“-d”以进行调试。应该可以在它们后面指定可选的名称空间。请参阅下面的代码段。问题在最后。
parser = argparse.ArgumentParser()
parser.add_argument('-v', '--verbose',
dest='verbose',
metavar='namespace',
nargs='*',
help='Sets the logging level to INFO.')
parser.add_argument('-d', '--debug,
dest='debug',
metavar='namespace',
nargs='*',
help='Sets the logging level to DEBUG.')
args = parser.parse_args()
if args.verbose:
print('verbose: ', args.verbose)
if args.debug:
print('debug: ', args.debug)
因此帮助用法类似于:
optional arguments:
-v [namespace [namespace ...]]
-d [namespace [namespace ...]]
我将它与类似下面的代码片段的内容一起使用。这只是您了解我的意图的背景信息。
logging_level = logging.INFO # just as example for -v
if not namespace:
logger = logging.getLogger()
logger.setLevel(logging_level)
else:
for n in namespace:
child_logger = logger.getChild(f'{root_module_name}.{namespace}')
child_logger.setLevel(logging_level)
问题
1.) 如果我调用 python my_module.py -v A -d B
输出会像预期的那样:
verbose: ['A']
debug: ['B']
2.) 如果我调用 python my_module.py -v -d
输出会像预期的那样:
verbose: []
debug: []
3.) 但是如果我调用 python my_module.py -vd
输出看起来像:
verbose: ['d']
debug: None
我要实现的是:
verbose: []
debug: []
4.) 如果我称它为 python my_module.py -vd B
error: unrecognized arguments: B
我要实现的是:
verbose: []
debug: ['B']
问题 是如何实现我想要的行为 3.) 和 4.)?
我知道我可以使用符合我要求的 python my_module.py --verbose --debug B
绕过这个问题。但这不是我要问的。
最简单的解决方案是不使用“-vd”输入。
'-vd' 被解析为 `-v d'。由于“-v”是一个带参数的短选项,它将以下字符串解释为一个值,而不是另一个标志。
您会期望“-vb”产生 ['b']
,对吧?为什么它对待“-vd”有什么不同?
人们更经常抱怨“-v -d”未能将“-d”视为“-v”的参数(通常是“-v”需要一个参数)。
'-vd' 将被解析为 '-v -d' 如果 '-v' 没有参数,例如如果它是 'store_true' (nargs=0
).
https://docs.python.org/3/library/argparse.html#option-value-syntax
For short options (options only one character long), the option and its value can be concatenated:
Several short options can be joined together, using only a single - prefix, as long as only the last option (or none of them) requires a value: