2015-12-31 15 views
5

Jestem zainteresowany użyciem argparsera ArgumentDefaultsHelpFormatter w klasie argparse (mój program ma kilka podrzędnych poleceń). Domyślnie argumenty wejściowe i wyjściowe są ustawione odpowiednio na sys.stdin i sys.stdout. Jednak formatowanie dla tych dwóch argumentów może być nieco dezorientujące dla użytkowników (np. (Domyślnie: ', tryb' r 'na 0x10028e0c0>). Czy istnieje sposób na konkretną i łatwą zmianę formatu wyjściowego dla tych dwóch argumentów, aby uzyskać coś jak 'domyślnie: STDIN' czy? 'domyślnie: STDOUT'Argparse i ArgumentDefaultsHelpFormatter. Formatowanie wartości domyślnych, gdy sys.stdin/stdout są wybrane domyślnie

Dziękuję

import sys 
import argparse 

parser = argparse.ArgumentParser(prog='PROG', 
           formatter_class=argparse.ArgumentDefaultsHelpFormatter) 

parser.add_argument('--infile', 
       '-i', 
       metavar='File', 
       help='The input file/stream.', 
       default=sys.stdin, 
       type=argparse.FileType('r'), 
       required=False) 

parser.add_argument('--outfile', 
       '-o', 
       metavar='File', 
       help='The output file/stream.', 
       default=sys.stdout, 
       type=argparse.FileType('r'), 
       required=False) 

parser.add_argument('--whatever-arg', 
       '-w', 
       type=str, 
       default='any', 
       help='Change something', 
       required=False) 


args = parser.parse_args() 
parser.print_help() 

co daje:

usage: PROG [-h] [--infile File] [--outfile File] 
      [--whatever-arg WHATEVER_ARG] 

optional arguments: 
    -h, --help   show this help message and exit 
    --infile File, -i File 
         The input file/stream. (default: <open file '<stdin>', 
         mode 'r' at 0x10028e0c0>) 
    --outfile File, -o File 
         The output file/stream. (default: <open file 
         '<stdout>', mode 'w' at 0x10028e150>) 
    --whatever-arg WHATEVER_ARG, -w WHATEVER_ARG 
         Change something (default: any) 
+0

Czy nie byłoby prostsze korzystanie z domyślnego formatyzatora i jawnie lista wartości domyślnych w pomocy?Inną opcją jest pominięcie 'FileType' i otwarcie plików później. 'FileType' jest wygodny dla małych skryptów, nie tak dobry dla dużych (gdzie potrzebujesz większej kontroli nad tym, kiedy pliki są otwarte). – hpaulj

+0

Mój program zawiera około 30 podprogramów, z których każdy ma własny zestaw argumentów. Dlatego bardzo wygodne jest użycie formatowania z wartościami domyślnymi. Mogę pominąć FileType, ale w takim przypadku nie będę korzystać z sprawdzania pliku argparse. – user451460

+0

Następnie dostosowywanie metody '_get_help_string' działa. To wszystko, co i tak robi standardowa klasa formatyzatora. – hpaulj

Odpowiedz

3

można podklasy ArgumentDefaultsHelpFormatter robić to, co chcesz

.
from argparse import ArgumentDefaultsHelpFormatter,RawDescriptionHelpFormatter 

class CustomFormatter(argparse.ArgumentDefaultsHelpFormatter, argparse.RawDescriptionHelpFormatter): 
    def _get_help_string(self, action): 
     help = action.help 
     if '%(default)' not in action.help: 
      if action.default is not argparse.SUPPRESS: 
       defaulting_nargs = [argparse.OPTIONAL, argparse.ZERO_OR_MORE] 
       if action.option_strings or action.nargs in defaulting_nargs: 
        if type(action.default) == type(sys.stdin): 
         print action.default.name 
         help += ' (default: ' + str(action.default.name) + ')' 
        else: 
         help += ' (default: %(default)s)' 
     return help 

parser = argparse.ArgumentParser(prog='PROG', formatter_class=CustomFormatter) 

wynik jest dla mnie:

optional arguments: 
    -h, --help   show this help message and exit 
    --infile File, -i File 
         The input file/stream. (default: <stdin>) 
    --outfile File, -o File 
         The output file/stream. (default: <stdout>) 
    --whatever-arg WHATEVER_ARG, -w WHATEVER_ARG 
         Change something (default: any) 
+0

Wcięcie po wyłączeniu funkcji "def". W przeciwnym razie koncepcja jest ważna. – hpaulj

+0

Bardzo dziękuję za pomoc. – user451460

2

Jeśli dasz default='-' zamiast sys.stdin wyświetlacz pomoc byłaby

the input file/stream. (default: -) 

Oznacza to, że pomaga pokazuje domyślny ciąg, ale FileType konwertuje '-' do wejścia/wyjścia.

Jak pokazuje A.H, można dostosować metodę _get_help_string. To nie ma znaczenia, który z klasy dziedziczyć, ponieważ modyfikacji tej metody jest wszystko, co robi ADHF:

class ArgumentDefaultsHelpFormatter(HelpFormatter): 
    """... 
    """ 
    def _get_help_string(self, action): 
     help = action.help 
     if '%(default)' not in action.help: 
      if action.default is not SUPPRESS: 
       defaulting_nargs = [OPTIONAL, ZERO_OR_MORE] 
       if action.option_strings or action.nargs in defaulting_nargs: 
        help += ' (default: %(default)s)' 
     return help 

I pamiętać, że cała ta modyfikacja nie jest dodać ciąg do parametru help - tylko (default: %(default)s)

Oznacza to, że można uzyskać podobny efekt, dostosowując własne linie help, np.

parser.add_argument('--infile', 
       '-i', 
       metavar='File', 
       help='The input file/stream, (default: stdin).', 
       default='-', 
       type=argparse.FileType('r')) 

parser.add_argument('--whatever-arg', 
       '-w', 
       default='any', 
       help='Change something, (default: %(default)s)') 

Innymi słowy oszczędza wpisując (default: %(default)s) na 28 swoich argumentów.

Jeśli nie lubisz dostosowywać klasę HelpFormatter (choć to jest to, co deweloperzy zalecają - z odpowiednimi przestrogami), możesz zmodyfikować własną konfigurację. Na przykład, zrobić prostą funkcję pomocnika, który dodaje dodatkowy ciąg do każdej linii pomocy:

def foohelp(astr): 
    return astr + ' (default: %(default)s)' 

arg1 = parser.add_argument('-f','--fooarg', help=foohelp('help string')) 

Mówiąc o zmianie konfiguracji programowo, to warto zauważyć, że add_argument tworzy obiekt Action. Możesz zapisać link do tego, tak jak tu zrobiłem, i poprawić parametry.

arg1 = parser.add_argument('-f','--fooarg', help='help string') 
print arg1.help 
arg1.help = foohelp(arg1.help) # modify help after creation 
print arg1.help 

Z 30 argumenty pewnie zrobili wiele kopii-n-wklej je określić, czy napisane różne funkcje pomocnicze usprawnić proces konfiguracji. Dodanie domyślnego wyświetlacza to tylko jedno z tych zadań. Możesz to zrobić podczas instalacji lub możesz to zrobić za pomocą niestandardowego formatyzatora.

+0

Są to również bardzo ładne rozwiązania. Bardzo dziękuję za Twoją pomoc. – user451460

Powiązane problemy