2012-05-25 9 views
10

argparse używa domyślnego skrótu w jednoznacznych przypadkach.Wyłącz skrót w argparse

Nie chcę skrótu i ​​chciałbym go wyłączyć. Ale nie znalazłem go w documentation.

Czy to możliwe?

Przykład:

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

Ale chcę tylko, żeby było prawdziwe, gdy jest dostarczany pełny parametr. Aby zapobiec błędom użytkownika.

UPDATE:

stworzyłem ticket at python bugtracker po Vikas odpowiedź. I to już zostało przetworzone.

Odpowiedz

5

Od Pythona 3.5.0 można wyłączyć skróty inicjując ArgumentParser z następujących czynności:

parser = argparse.ArgumentParser(allow_abbrev=False) 

zobaczyć również the documentation.

+0

Mimo że oryginalne pytanie pochodziło sprzed ponad 3 lat, jest to poprawna odpowiedź na dzień dzisiejszy. – jdferreira

+0

Wybieram to jako poprawną odpowiedź, ponieważ jest bardziej odpowiednie teraz. – jens

3

Nie, najwyraźniej nie jest to możliwe. Przynajmniej w Pythonie 2.7.2.

Najpierw zajrzałem do dokumentacji - bezskutecznie.

Następnie otworzyłem plik Lib \ argparse.py i przejrzałem kod źródłowy. Pomijając wiele szczegółów, wydaje się, że każdy argument jest analizowany za pomocą wyrażenia regularnego tak (argparse: 2152):

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

To wyrażenie regularne będzie skutecznie analizować zarówno „-” i „-”, więc mamy brak kontroli nad krótkimi i długimi argumentami. Inne wyrażenia regularne również używają konstrukcji - *, więc nie zależy ona od typu parametru (żadnych podargumentów, 1 pod-argumentu itp.).

Później w kodzie podwójne kreski są konwertowane na jednej desce rozdzielczej (tylko dla non-opcjonalne args), ponownie, bez żadnych flag do sterowania przez użytkownika:

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

Niezłe badania :) –

+0

Nie sądzę, że problem ma coś wspólnego z krótkimi i długimi opcjami. – Vikas

4

Nie, nie jest dobrze bez brzydkich sztuczek.

Fragment kodu @Vladimir opublikowany, przypuszczam, że to nie jest to, czego szukasz. Rzeczywisty kod, który robi to:

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

Zobacz czek jest startswith nie ==.

Zawsze można przedłużyć argparse.ArgumentParser, aby wprowadzić własne _get_option_tuples(self, option_string), aby zmienić to zachowanie. Ja po prostu nie zastępując dwa wystąpienia option_string.startswith(option_prefix) do option_string == option_prefix i:

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

Jedna uwaga

Sposób _get_option_tuples jest poprzedzona _, który zazwyczaj oznacza prywatną metodę w Pythonie. I nie jest dobrym pomysłem pominięcie prywatnego.

+0

Tak, tego właśnie szukałem. thx – jens

3

Inny sposób dla Pythona 2.7. Zdobądźmy się przygnębiająco! Załóżmy, że chcesz rozpoznać skrót --dog.

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

Dodając drugi argument --dox który różni się od argumentu chcesz tylko w trzecim piśmie --d i --do stać się niejednoznaczne. Dlatego parser odmówi ich rozpoznania. Będziesz musiał dodać kod, aby wychwycić wynikowy wyjątek i przetworzyć go zgodnie z kontekstem, w którym dzwonisz: parse_args. Może być również konieczne tłumienie/modyfikowanie tekstu pomocy.

help=... utrzymuje argument z listy opcji na komunikat domyślny pomocy (za this) i metavar='IGNORE' jest tylko aby było jasne, że naprawdę nie robią nic z tej opcji :).

+0

@ 2rs2ts Kolejna opcja dla Ciebie. – cxw

+0

Taa, przyda mi się, ponieważ nie mam dostępu do Pythona 3.5 przez moje bieżące repozyty apt. Dzięki! – 2rs2ts