带有所需子解析器的 Argparse [英] Argparse with required subparser

查看:21
本文介绍了带有所需子解析器的 Argparse的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm using Python 3.4, I'm trying to use argparse with subparsers, and I want to have a similar behavior to the one in Python 2.x where if I don't supply a positional argument (to indicate the subparser/subprogram) I'll get a helpful error message. I.e., with python2 I'll get the following error message:

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

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

I'm setting the required attribute as suggested in https://stackoverflow.com/a/22994500/3061818, however that gives me an error with Python 3.4.0: TypeError: sequence item 0: expected str instance, NoneType found - full traceback:

$ 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:

This is my program subparser_test.py - adapted from 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 之间的行为不同?

推荐答案

你需要给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

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

In order to issue this 'missing arguments' error message, the code needs to give that argument a name. For a positional argument (like subparses), that name is (by default) the 'dest'. There's a (minor) note about this in the SO answer you linked.

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

One of the few 'patches' to argparse in the last Python release changed how it tests for 'required' arguments. Unfortunately it introduced this bug regarding subparsers. This needs to be fixed in the next release (if not sooner).

如果你想在 Py2 中使用这个可选的子解析器行为,看起来最好的选择是使用

If you want this optional subparsers behavior in Py2, it looks like the best option is to use a two stage parser as described in

如何设置使用 Argparse 模块和 Python 2.7 的默认子解析器

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

There has been some recent activity in the related bug/issue

https://bugs.python.org/issue9253

正在修复此问题:https://github.com/python/cpython/pull/3027

这篇关于带有所需子解析器的 Argparse的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆