Отключить аббревиатуру в argparse

argparse использует аббревиатуру по умолчанию в недвусмысленных случаях.

Я не хочу аббревиатуры, и я бы хотел отключить его. Но не нашел его в документации.

Возможно ли это?

Пример:

import argparse
parser = argparse.ArgumentParser()
parser.add_argument('--send', action='store_true')
parser.parse_args(['--se']) # returns Namespace(send=True)

Но я хочу, чтобы это было верно, только когда задан полный параметр. Чтобы предотвратить ошибки пользователя.

UPDATE:

Я создал билет в python bugtracker после ответа Vikas. И он уже обработан.

Ответ 1

Как и в случае с Python 3.5.0, вы можете отключить аббревиатуры, инициировав ArgumentParser следующим образом:

parser = argparse.ArgumentParser(allow_abbrev=False)

Также см. документацию.

Ответ 2

Нет, ну не без уродливых хаков.

Фрагмент кода @Vladimir опубликовал, я полагаю, это не то, что вы ищете. Фактический код, который делает это:

def _get_option_tuples(self, option_string):
    ...
    if option_string.startswith(option_prefix):
    ...

См. чек startswith not ==.

И вы всегда можете расширить argparse.ArgumentParser, чтобы предоставить свой собственный _get_option_tuples(self, option_string), чтобы изменить это поведение. Я просто сделал, заменив два появления option_string.startswith(option_prefix) на option_string == option_prefix и:

>>> parser = my_argparse.MyArgparse
>>> parser = my_argparse.MyArgparse()
>>> parser.add_argument('--send', action='store_true')
_StoreTrueAction(option_strings=['--send'], dest='send', nargs=0, const=True, default=False, type=None, choices=None, help=None, metavar=None)
>>> parser.parse_args(['--se'])
usage: [-h] [--send]
: error: unrecognized arguments: --se

Слово предостережения

Метод _get_option_tuples имеет префикс _, который обычно означает частный метод в python. И не рекомендуется переопределять частные.

Ответ 3

Нет, видимо, это невозможно. По крайней мере, в Python 2.7.2.

Во-первых, я просмотрел документацию - безрезультатно.

Затем я открыл Lib\argparse.py и просмотрел исходный код. Опуская множество деталей, кажется, что каждый аргумент анализируется регулярным выражением (argparse: 2152):

    # allow one or more arguments
    elif nargs == ONE_OR_MORE:
        nargs_pattern = '(-*A[A-]*)'

Это регулярное выражение будет успешно анализировать как "-", так и "-", поэтому мы не можем контролировать короткие и длинные аргументы. Другие регулярные выражения также используют конструкцию - *, поэтому она не зависит от типа параметра (без подпараметров, 1 подзаголовка и т.д.).

Позже в коде двойные тире преобразуются в одну тире (только для необязательных аргументов), опять же, без каких-либо флагов для управления пользователем:

    # if this is an optional action, -- is not allowed
    if action.option_strings:
        nargs_pattern = nargs_pattern.replace('-*', '')
        nargs_pattern = nargs_pattern.replace('-', '')

Ответ 4

Другой способ для Python 2.7. Пусть будет неуклюже! Скажем, вы хотите распознать --dog без аббревиатуры.

p = argparse.ArgumentParser()
p.add_argument('--dog')
p.add_argument('--dox', help=argparse.SUPPRESS, metavar='IGNORE')

Добавив второй аргумент --dox, который отличается от аргумента, который вы хотите только в третьей букве, --d и --do становятся неоднозначными. Поэтому анализатор откажется их распознавать. Вам нужно будет добавить код, чтобы поймать полученное исключение и обработать его в соответствии с контекстом, в котором вы вызываете parse_args. Вам также может потребоваться подавить/настроить текст справки.

help=... сохраняет аргумент из списка параметров в справочном сообщении по умолчанию (за this), а metavar='IGNORE' - это просто чтобы было ясно, что вы действительно ничего не делаете с этой опцией:).