python argparse-настройка сообщений об ошибках

Я хочу генерировать пользовательские сообщения об ошибках для определенных ошибок использования в моей программе командной строки, которая использует argparse библиотека. Я знаю, что могу переопределить общее представление ошибки путем подкласса argparse.ArgumentParser:

class HelpParser(argparse.ArgumentParser):
    def error(self, message):
        sys.stderr.write('error: %sn' % 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'

?

2 ответов


смотрим исходный код, вы могли бы за-ехать this particular сообщение об ошибке путем переопределения этого метода:

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)

проблема в том, что если вы хотите переопределить все возможные сообщения об ошибках, вам придется в основном переписать этот модуль. Все различные сообщения об ошибках предварительно отформатированы повсюду-в различных методах, которые обнаруживают каждый тип ошибки.


добавление к ответу @Геррат, то _ функция импортируется как

from gettext import gettext as _, ngettext

С gettext модуль,https://docs.python.org/2/library/gettext.html, чтобы включить интернационализацию. Я не знаком с этим модулем, но предположительно вы можете использовать его для выполнения определенного количества английских перефразирований. Но, может быть, не так сильно, как тебе хотелось бы.

сообщения об ошибках проходят через несколько уровней. Функции как _check_values написать основной сообщение. ArgumentError добавляет имя аргумента (argument subparser: в вашем примере). parser.error добавляет usage и prog. parser.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)