为什么此 argparse 代码在 Python 2 和 3 之间的行为不同? [英] Why does this argparse code behave differently between Python 2 and 3?
问题描述
以下代码,使用 argparse 的子解析器,在 Python 3 上失败,但在 Python 2 中按预期运行.比较文档后,我仍然不知道为什么.
The following code, using argparse's subparsers, fails on Python 3 but runs as expected in Python 2. After comparing the docs, I still can't tell why.
#!/usr/bin/env python
from __future__ import print_function
from argparse import ArgumentParser
def action(args):
print(args)
if __name__ == '__main__':
std = ArgumentParser(add_help=False)
std.add_argument('standard')
ap = ArgumentParser()
sp = ap.add_subparsers()
cmd = sp.add_parser('subcommand', parents=[std], description='Do subcommand')
cmd.add_argument('arg')
cmd.set_defaults(do=action)
args = ap.parse_args()
args.do(args)
Python 2.7.6 的输出是:
The output from Python 2.7.6 is:
me@computer$ python test.py
usage: test.py [-h] {subcommand} ...
test.py: error: too few arguments
在 Python 3.3.5 中,我得到:
In Python 3.3.5, I get:
me@computer$ python3 test.py
Traceback (most recent call last):
File "test.py", line 21, in <module>
args.do(args)
AttributeError: 'Namespace' object has no attribute 'do'
推荐答案
最新的 argparse
版本改变了它测试所需参数的方式,并且子解析器失败了.它们不再是必需的".http://bugs.python.org/issue9253#msg186387
the latest argparse
release changed how it tested for required arguments, and subparsers fell through the cracks. They are no longer 'required'. http://bugs.python.org/issue9253#msg186387
当你得到 test.py: error: too few arguments
时,它反对你没有给它一个子命令"参数.在 3.3.5 中,它通过了这一步,并返回 args
.
When you get test.py: error: too few arguments
, it's objecting that you did not give it a 'subcommand' argument. In 3.3.5 it makes it past that step, and returns args
.
通过此更改,3.3.5 的行为应与早期版本相同:
With this change, 3.3.5 should behave the same as earlier versions:
ap = ArgumentParser()
sp = ap.add_subparsers(dest='parser') # dest needed for error message
sp.required = True # force 'required' testing
注意 - dest
和 required
都需要设置.需要 dest
在错误消息中给这个参数一个名字.
Note - both dest
and required
need to be set. dest
is needed to give this argument a name in the error message.
这个错误:
AttributeError: 'Namespace' object has no attribute 'do'
的产生是因为 cmd
子解析器没有运行,并且没有将其参数(默认或不)放入命名空间.您可以通过定义另一个子解析器并查看结果 args
来看到这种效果.
was produced because the cmd
subparser did not run, and did not put its arguments (default or not) into the namespace. You can see that effect by defining another subparser, and looking at the resulting args
.
这篇关于为什么此 argparse 代码在 Python 2 和 3 之间的行为不同?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!