当前位置: 首页 > 面试题库 >

为什么此argparse代码在Python 2和3之间的行为不同?

墨宜人
2023-03-14
问题内容

以下使用argparse的子解析器的代码在Python 3上失败,但在Python 2中按预期运行。在比较了文档之后,我仍然不知道为什么。

#!/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的输出为:

me@computer$ python test.py 
usage: test.py [-h] {subcommand} ...
test.py: error: too few arguments

在Python 3.3.5中,我得到:

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

当您获得时test.py: error: too few arguments,就会反对您没有给它一个“子命令”参数。在3.3.5中,它经过了该步骤,然后返回args

进行此更改后,3.3.5的行为应与早期版本相同:

ap = ArgumentParser()
sp = ap.add_subparsers(dest='parser')  # dest needed for error message
sp.required = True   # force 'required' testing

注-既destrequired需要进行设置。 dest需要在错误消息中为此参数命名。

这个错误:

AttributeError: 'Namespace' object has no attribute 'do'

之所以生成该cmd文件,是因为该子解析器未运行,并且没有将其参数(默认值或未设置)放入名称空间。您可以通过定义另一个子解析器并查看结果来查看效果args



 类似资料:
  • 问题内容: var x int done := false go func() { x = f(…); done = true } while done == false { } 这是Go代码。我的恶魔告诉我,这是UB代码。为什么? 问题答案: Go Memory Model不保证该程序将始终遵守在goroutine中写入x的值。go常规销毁 部分中提供了一个类似的错误程序作为示例。 在本节中,G

  • 问题内容: 为什么这段代码不抛出?它在不使用方法的情况下修改了一段时间,这是唯一安全的删除方法。 如果将替换为,则会得到相同的结果。但是,如果我将列表更改为或只是得到了预期的异常。到底是怎么回事?我正在使用是否相关。 编辑 我找到了以下链接 http://bugs.java.com/bugdatabase/view_bug.do?bug_id=4902078 相关部分是 天真的解决方案是将协同修改

  • 问题内容: 我想知道以下代码的行为背后的机制是什么: 我的理解是不 返回 函数,而是 关闭连接/结束请求 。这可以解释为什么我仍然可以在命令后执行代码(我查看了快速源,但它似乎不是异步函数)。 还有其他我可能会想念的东西吗? 问题答案: 当然可以结束HTTP响应,但是它对您的代码没有做任何特殊的事情。 即使您已结束回复,也可以继续做其他事情。 但是,您 无法 做的是利用进行任何有用的操作。由于响应

  • 显然,我希望答案是肯定的,所以首先我尝试了,但结果是1。我推断这是因为Python将计算为。为了解决这个问题,我发现可以使用,问题解决了。 但我找到了另一个解决方案,即(为了进行比较,我包含了前面的示例): 我无法解释为什么包括0有帮助。我已经阅读了关于“组织”的文件,但我在那里没有找到任何帮助。我以为可能是因为评审顺序的原因: null

  • 问题内容: 我编写了以下程序: 由于通道事件列表是一个缓冲通道,我想我应该获得100倍的输出“嘿!”,但是它只显示一次。我的错误在哪里? 问题答案: 更新(Go 1.2版或更高版本) 从Go 1.2开始,调度程序基于 抢先式多任务处理 原则。这意味着原始问题(以及下面提供的解决方案)中的问题不再相关。 从Go 1.2发行说明中 调度程序中的抢占 在以前的版本中,永远循环的goroutine可能会使