如何使用ArgumentParser和两个短的可选参数,它们都接受nargs =' *'

时间:2018-02-12 17:03:03

标签: python-3.x argparse

我试图为我的项目配备一个由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来绕过此问题。但这不是我所要求的。

1 个答案:

答案 0 :(得分:1)

最简单的解决方案是不要使用'-vd'输入。

' - vd'被解析为`-v d'。由于'-v'是一个带参数的短选项,它将后面的字符串解释为值,而不是另一个标志。

你会期望'-vb'产生['b'],对吗?为什么它应该对待'-vd'有什么不同?

更多时候人们抱怨'-v -d'没有将'-d'视为'-v'的参数(通常当'-v'需要一个参数时)。

如果'-v'没有参数,

' - vd'将被解析为'-v -d',例如它是'store_true'(nargs=0)。

https://docs.python.org/3/library/argparse.html#option-value-syntax

  

对于短选项(选项只有一个字符长),可以连接选项及其值:

     

只要使用单个前缀,只要最后一个选项(或者没有一个)需要值,就可以将几个短选项连接在一起: