2012-05-25 3 views
10

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

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

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

Пример:

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

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

UPDATE:

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

ответ

5

От Python 3.5.0 Вы можете отключить сокращения, инициируя ArgumentParser со следующим:

parser = argparse.ArgumentParser(allow_abbrev=False) 

Также см the documentation.

+0

Хотя исходный вопрос был более трех лет назад, это правильный ответ на сегодняшний день. – jdferreira

+0

Я выбираю это как правильный ответ, потому что теперь он более подходящий. – jens

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('-', '') 
+1

Хорошее исследование :) –

+0

Я не думаю, что проблема имеет какое-либо отношение к коротким и длинным вариантам. – Vikas

4

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

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

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

Смотрите чек startswith не ==.

И вы всегда можете продлить 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. И не стоит переопределять частные.

+0

да, это то, что я искал. thx – jens

3

Другой способ для 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' просто чтобы понять, вы на самом деле ничего с этим вариантом :) не делать.

+0

@ 2rs2ts Еще один вариант для вас. – cxw

+0

Да, это будет полезно для меня, так как у меня даже нет доступа к Python 3.5 через мои текущие репозитории. Благодаря! – 2rs2ts

Смежные вопросы