带有必需子解析器的Argparse


74

我正在使用Python 3.4,正在尝试argparse与子解析器一起使用,并且我希望具有与Python 2.x中类似的行为,如果我不提供位置参数(以指示子解析器/子程序)我会收到一条有用的错误消息。即,随着python2我将得到以下错误消息:

$ python2 subparser_test.py    
usage: subparser_test.py [-h] {foo} ...
subparser_test.py: error: too few arguments

我正在required按照https://stackoverflow.com/a/22994500/3061818中的建议设置属性,但是这给我Python 3.4.0带来了错误: TypeError: sequence item 0: expected str instance, NoneType found-完全回溯:

$ python3 subparser_test.py    
Traceback (most recent call last):
  File "subparser_test.py", line 17, in <module>
    args = parser.parse_args()
  File "/usr/local/Cellar/python3/3.4.0/Frameworks/Python.framework/Versions/3.4/lib/python3.4/argparse.py", line 1717, in parse_args
    args, argv = self.parse_known_args(args, namespace)
  File "/usr/local/Cellar/python3/3.4.0/Frameworks/Python.framework/Versions/3.4/lib/python3.4/argparse.py", line 1749, in parse_known_args
    namespace, args = self._parse_known_args(args, namespace)
  File "/usr/local/Cellar/python3/3.4.0/Frameworks/Python.framework/Versions/3.4/lib/python3.4/argparse.py", line 1984, in _parse_known_args
    ', '.join(required_actions))
TypeError: sequence item 0: expected str instance, NoneType found

这是我的程序subparser_test.py-改编自https://docs.python.org/3.2/library/argparse.html#sub-commands

import argparse

# sub-command functions
def foo(args):
    print('"foo()" called')

# create the top-level parser
parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers()
subparsers.required = True

# create the parser for the "foo" command
parser_foo = subparsers.add_parser('foo')
parser_foo.set_defaults(func=foo)

args = parser.parse_args()
args.func(args)

相关问题:为什么此argparse代码在Python 2和3之间的行为不同?

Answers:


112

您需要给subparsers一个dest

parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers(dest='cmd')
subparsers.required = True

现在:

1909:~/mypy$ argdev/python3 stack23349349.py
usage: stack23349349.py [-h] {foo} ...
stack23349349.py: error: the following arguments are required: cmd

为了发出此“缺少参数”错误消息,代码需要给该参数命名。对于位置自变量(如子表达式),该名称(默认情况下)为“目标”。在您链接的SO答案中有一个(次要)说明。

argparse在上一个Python版本中,为数不多的“补丁”之一改变了它测试“必需”参数的方式。不幸的是,它引入了有关次解析器的错误。此问题需要在下一个版本中解决(如果不能尽快)。

更新

如果您希望在Py2中具有此可选的子解析器行为,则最好的选择是使用两阶段解析器,如所述。

如何在python 2.7中使用Argparse模块设置默认子解析器

相关的错误/问题中有一些近期活动

https://bugs.python.org/issue9253

更新

正在对此进行修复:https : //github.com/python/cpython/pull/3027


有关argparse错误的更多信息,请参见此处。提出这个答案似乎有助于提高其在Python错误队列中的紧迫性。真的,我不仅仅是为某人耕种代表!
Pedro

更新:由于“兼容性”原因,修复已恢复:bugs.python.org/issue33109- 猜猜此错误将永远存在
Anthony Sottile,

8
由于Python 3.7required可以用作参数:parser.add_subparsers(dest='cmd', required=True)docs.python.org
Henrik
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.