Ответ 1
Как и в случае с Python 3.5.0, вы можете отключить аббревиатуры, инициировав ArgumentParser следующим образом:
parser = argparse.ArgumentParser(allow_abbrev=False)
Также см. документацию.
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. И он уже обработан.
Как и в случае с Python 3.5.0, вы можете отключить аббревиатуры, инициировав ArgumentParser следующим образом:
parser = argparse.ArgumentParser(allow_abbrev=False)
Также см. документацию.
Нет, ну не без уродливых хаков.
Фрагмент кода @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. И не рекомендуется переопределять частные.
Нет, видимо, это невозможно. По крайней мере, в 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('-', '')
Другой способ для 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'
- это просто чтобы было ясно, что вы действительно ничего не делаете с этой опцией:).