Python argparse-自定义错误消息

13

我希望为我的命令行程序中使用的特定用法错误生成自定义错误消息,该程序使用argparse库。我知道可以通过子类化argparse.ArgumentParser来覆盖一般错误的呈现:

class HelpParser(argparse.ArgumentParser):
    def error(self, message):
        sys.stderr.write('error: %s\n' % message)
        sys.exit(2)

parser = HelpParser(... ...)
args = parser.parse_args()

但是当我的error方法被调用时,message已经被库格式化了。例如,

> python prog.py old stuff

usage: prog [-h] {hot,cold,rain,snow} ...
prog: error: argument subparser: invalid choice: 'old' (choose from u'hot', u'cold', u'rain', u'snow')

我该如何改变“error:”后面的信息呈现方式?例如,将其改为
usage: prog [-h] {hot,cold,rain,snow} ...
error: 'old' is not a valid option. select from 'hot', 'cold', 'rain', 'snow'

?


我修改了你的问题陈述,因为据我所知,它与异常(语言功能)没有任何关系。如果我误解了你想要问的内容,请告诉我。 - zwol
你使用的是哪个Python版本和操作系统?我在Windows上尝试了Python 3.4,但是我没有遇到你所说的问题。 - Anand S Kumar
@zwol的问题读起来好多了。谢谢! - Henry Thornton
2个回答

6

查看源代码,您可以通过重写此方法来覆盖特定的错误消息:

def _check_value(self, action, value):
    # converted value must be one of the choices (if specified)
    if action.choices is not None and value not in action.choices:
        args = {'value': value,
                'choices': ', '.join(map(repr, action.choices))}
        msg = _('invalid choice: %(value)r (choose from %(choices)s)')
        raise ArgumentError(action, msg % args)

问题在于,如果您想覆盖所有可能的错误消息,您基本上需要重新编写此模块。各种错误消息已经在整个模块中预先格式化 - 在检测每种类型的错误的各种方法中。

1
发布问题后,我开始意识到可能没有通用解决方案。就像你所说的那样,你必须重新编写模块以提供定制错误消息,这违背了初衷。 - Henry Thornton
1
@HenryThornton 现在应该有一个自定义错误潜力的PEP,但目前还没有。 - theX

1

补充@Gerrat的回答,_函数被导入为

from gettext import gettext as _, ngettext

它使用gettext模块https://docs.python.org/2/library/gettext.html来启用国际化。我不熟悉该模块,但可能可以使用它进行一定程度的英语释义。但也许不如您所希望的那么多。
错误消息通过几个级别传递。像_check_values这样的函数编写基本消息。ArgumentError添加参数名称(在您的示例中为argument subparser:)。parser.error添加usageprogparser.exit处理sys.exit步骤。
def error(self, message):
    ...
    self.print_usage(_sys.stderr)
    args = {'prog': self.prog, 'message': message}
    self.exit(2, _('%(prog)s: error: %(message)s\n') % args)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接