【问题标题】:I want Python argparse to throw an exception rather than usage我希望 Python argparse 抛出异常而不是使用
【发布时间】:2013-01-21 14:38:45
【问题描述】:

我认为这是不可能的,但我想自己处理来自 argparse 的异常。

例如:

import argparse
parser = argparse.ArgumentParser()
parser.add_argument('--foo', help='foo help', required=True)
try:
    args = parser.parse_args()
except:
    do_something()

当我运行它时:

$ myapp.py
usage: myapp --foo foo
myapp: error: argument --foo is required

但我希望它改为属于异常。

【问题讨论】:

  • 那么,您没有将 argparse 用于它的设计目的。你想做什么?
  • 改变一个原本很棒的库的工作方式并不是一件坏事,只是将其调整到特定的项目。
  • 其实你已经可以做到了。只需捕获 SystemExit 并将 sys.stderr 替换为其他对象即可。
  • @jdborg:这不是必然不好,但通常是不好的。在这种情况下,我想听听您想要实现的目标——很可能会有更好的方法。
  • 根据你想要做什么,修改参数本身可能会更好。 --foo 的参数是可选的吗?你能定义一个自定义动作来处理它吗?这些可能比覆盖argparse 的退出决定更干净。

标签: python argparse


【解决方案1】:

您可以继承 ArgumentParser 并覆盖 error 方法以在发生错误时执行不同的操作:

class ArgumentParserError(Exception): pass

class ThrowingArgumentParser(argparse.ArgumentParser):
    def error(self, message):
        raise ArgumentParserError(message)

parser = ThrowingArgumentParser()
parser.add_argument(...)
...

【讨论】:

  • 以为会是这样。感谢您的明确答复。
  • 我希望避免这样的事情,尽管我很高兴这是一个选项。你看,当我收到“错误:参数太少”通知时,我正在尝试打印帮助菜单;我的 argparse 设置至少需要一个参数才能成功运行,但我认为打印出这些命令是什么而用户不必使用“-h”参数运行脚本会很有礼貌。像:parser.set_error('too few arguments', method_to_deal_with_error) 我想如果我想要这个功能,我总是可以提交一个错误。谢谢!
【解决方案2】:

在我的情况下,argparse 打印“参数太少”然后退出。阅读 argparse 代码后,我发现它只是在打印一些消息后调用 sys.exit() 。由于 sys.exit() 只会抛出 SystemExit 异常,因此您只需捕获此异常即可。

所以试试这个,看看它是否适合你。

    try:
        args = parser.parse_args(args)
    except SystemExit:
        .... your handler here ...
        return

【讨论】:

  • 是的,上面 Bakuriu 的评论中提到了这个选项。单元测试test_argparse.py 文件使用这种方法,同时重新定义error 以创建ErrorRaisingArgumentParser 类。
  • 错误信息在标准错误中被抛出。有没有办法抓住它?
  • @Raj 您可以临时将stderr重定向到另一个流/文件对象,例如:stackoverflow.com/a/6796752/2128769
猜你喜欢
  • 2022-01-03
  • 2017-04-01
  • 1970-01-01
  • 2012-01-24
  • 2012-07-09
  • 2014-03-26
  • 1970-01-01
  • 2019-10-17
  • 2021-04-17
相关资源
最近更新 更多