关于python:带有必需subparser的Argparse

Argparse with required subparser

我使用的是python 3.4,我试图将argparse与子分区一起使用,我希望具有与python 2.x中类似的行为,如果不提供位置参数(指示子分区/子程序),我将收到一条有用的错误消息。也就是说,使用EDOCX1[1]时,我会收到以下错误消息:

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

我正在按照https://stackoverflow.com/a/22994500/3061818中的建议设置required属性,但是这会给我一个关于python 3.4.0的错误:TypeError: sequence item 0: expected str instance, NoneType foundfull traceback:

1
2
3
4
5
6
7
8
9
10
11
$ 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子命令:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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代码在python2和3之间的行为不同?


你需要给subparsers一个dest

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

现在:

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

为了发出此"缺少参数"错误消息,代码需要为该参数命名。对于位置参数(如子段),该名称(默认情况下)为"dest"。在你链接的SO答案中有一个(小)注释。

在上一个Python版本中,argparse的少数"补丁"之一改变了它测试"必需"参数的方式。不幸的是,它引入了这个关于子分区的错误。这需要在下一个版本中修复(如果不早的话)。

更新

如果希望在PY2中使用此可选的子排序器行为,那么最好的选择似乎是使用两阶段分析器,如中所述。

如何使用argparse模块和python 2.7设置默认子排序器

最近在相关的Bug/Issue中有一些活动

https://bugs.python.org/issue9253

更新

解决这个问题的方法正在研究中:https://github.com/python/cpython/pull/3027