2012-05-25 9 views
10

argparse utiliza por abreviatura predeterminada en casos no ambiguos.Deshabilitar abreviatura en argparse

No quiero abreviar y me gustaría desactivarlo. Pero no lo encontré en el documentation.

¿Es posible?

Ejemplo:

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

Pero quiero que sólo es cierto cuando se suministra el parámetro completo. Para evitar errores de usuario

ACTUALIZACIÓN:

que creó un ticket at python bugtracker después de la respuesta Vikas. Y ya ha sido procesado.

Respuesta

5

A partir de Python 3.5.0 puede desactivar abreviaturas iniciando la ArgumentParser con lo siguiente:

parser = argparse.ArgumentParser(allow_abbrev=False) 

también ver the documentation.

+0

Aunque la pregunta original era de hace más de 3 años, esta es la respuesta correcta a día de hoy. – jdferreira

+0

selecciono esto como la respuesta correcta, porque ahora es más apropiado. – jens

3

No, aparentemente esto no es posible. Al menos en Python 2.7.2.

Primero, eché un vistazo a la documentación, fue en vano.

Luego abrí Lib \ argparse.py y miré a través del código fuente. La omisión de una gran cantidad de detalles, parece que cada argumento se analiza por una expresión regular como esta (argparse: 2152):

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

Esta expresión regular analizar correctamente tanto '-' y '-', por lo que tenemos sin control sobre los argumentos cortos y largos. Otras expresiones regulares también usan el constructo - *, por lo que no depende del tipo del parámetro (sin subargumentos, 1 subargumento, etc.).

Más adelante en el código guiones dobles se convierten a un guión (sólo para args no opcionales), de nuevo, sin ningún tipo de banderas para controlar por el usuario:

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

Buena investigación :) –

+0

No creo que el problema tenga algo que ver con las opciones cortas y largas. – Vikas

4

No, así no sin hacks feo.

El fragmento de código @Vladimir publicado, supongo que no es lo que estás buscando. El código real que está haciendo esto es:

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

Ver el cheque es startswith no ==.

Y siempre puede ampliar argparse.ArgumentParser para proporcionar su propio _get_option_tuples(self, option_string) para cambiar este comportamiento. Acabo de hacer mediante la sustitución de dos ocurrencia de option_string.startswith(option_prefix)-option_string == option_prefix y:

>>> 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 

Una palabra de precaución

El método _get_option_tuples se prefija con _, que normalmente significa un método privado en Python. Y no es una buena idea anular un privado.

+0

sí esto era lo que estaba buscando. thx – jens

3

Otra forma para Python 2.7. ¡Seamos torpes! Digamos que quiere reconocer --dog sin abreviatura.

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

Mediante la adición de un segundo argumento --dox que difiere de la discusión que desea sólo en la tercera letra, --d y --do se convierten ambigua. Por lo tanto, el analizador se negará a reconocerlos. Debería agregar un código para capturar la excepción resultante y procesarla según el contexto en el que está llamando al parse_args. Es posible que también deba suprimir/ajustar el texto de ayuda.

El help=... mantiene el argumento de la lista de opciones en el mensaje de ayuda predeterminado (por this), y metavar='IGNORE' es sólo para que quede claro que realmente no está haciendo nada con esta opción :).

+0

@ 2rs2ts Otra opción para usted. – cxw

+0

Sí, esto me será útil ya que ni siquiera tengo acceso a Python 3.5 a través de mis repos apt actuales. ¡Gracias! – 2rs2ts