2012-05-25 2 views
10

argparse utilizza l'abbreviazione predefinita in casi non ambigui.Disabilita abbreviazione in argparse

Non voglio l'abbreviazione e mi piacerebbe disabilitarla. Ma non lo trova nel documentation.

È possibile?

Esempio:

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

Ma voglio solo per essere vero quando il parametro completo è fornito. Per evitare errori dell'utente.

UPDATE:

ho creato un ticket at python bugtracker dopo Vikas risposta. Ed è già stato elaborato.

risposta

5

A partire da Python 3.5.0 è possibile disattivare le abbreviazioni avviando l'ArgumentParser con il seguente:

parser = argparse.ArgumentParser(allow_abbrev=False) 

vedere anche the documentation.

+0

Anche se la domanda originale era di più di 3 anni fa, questa è la risposta corretta a partire da oggi. – jdferreira

+0

lo seleziono come risposta corretta, perché ora è più appropriato. – jens

3

No, a quanto pare non è possibile. Almeno in Python 2.7.2.

In primo luogo, ho dato un'occhiata alla documentazione - senza alcun risultato.

Quindi ho aperto Lib \ argparse.py e ho guardato attraverso il codice sorgente. Tralasciando un sacco di dettagli, sembra che ogni argomento viene analizzato da un'espressione regolare come questo (argparse: 2152):

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

Questa espressione regolare sarà successo analizzare sia '-' e '-', quindi abbiamo nessun controllo sugli argomenti brevi e lunghi. Altre regex usano anche il costrutto - *, quindi non dipende dal tipo del parametro (niente argomenti secondari, 1 argomento secondario ecc.).

Più avanti nel codice doppi trattini vengono convertiti in un trattino (solo per args non opzionali), ancora una volta, senza bandiere per il controllo da parte dell'utente:

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

Bella ricerca :) –

+0

Non penso che il problema abbia nulla a che fare con le opzioni brevi e lunghe. – Vikas

4

No, beh non senza brutte hack.

Lo snippet di codice @Vladimir pubblicato, suppongo che non sia quello che stai cercando. Il codice effettivo che sta facendo questo è:

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

Vedi l'assegno non è startswith==.

E è sempre possibile estendere argparse.ArgumentParser per fornire il proprio _get_option_tuples(self, option_string) per modificare questo comportamento. Ho appena fatto sostituendo due occorrenza di option_string.startswith(option_prefix) a option_string == option_prefix e:

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

Un avvertimento

Procedimento _get_option_tuples è prefissato con _, che in genere significa un metodo privato in pitone. E non è una buona idea ignorare un privato.

+0

sì, questo era quello che stavo cercando. thx – jens

3

Un altro modo per Python 2.7. Diventiamo goffo! Supponi di voler riconoscere --dog senza abbreviazioni.

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

Con l'aggiunta di un secondo argomento --dox che differisce dalla argomento desideri solo nella terza lettera, --d e --do diventano ambigue. Pertanto, il parser rifiuterà di riconoscerli. Dovresti aggiungere del codice per catturare l'eccezione risultante ed elaborarlo in base al contesto in cui stai chiamando parse_args. Potrebbe anche essere necessario sopprimere/modificare il testo della guida.

Il help=... mantiene l'argomento fuori dalla lista delle opzioni sul messaggio di aiuto di default (per this), e metavar='IGNORE' è solo per far capire davvero non sta facendo nulla con questa opzione :).

+0

@ 2rs2ts Un'altra opzione per voi. – cxw

+0

Sì, questo sarà utile per me dal momento che non ho nemmeno accesso a Python 3.5 attraverso i miei repository apt attuali. Grazie! – 2rs2ts