2016-03-07 8 views
15

Napisałem poniższy przykładowy kod, aby zademonstrować mój problem.Dostosuj komunikat pomocy argparse

import argparse 

parser = argparse.ArgumentParser() 
parser.add_argument('-v', '--version', action='version', 
        version='%(prog)s 1.0') 
parser.parse_args() 

Powoduje wyświetlenie następującego komunikatu pomocy.

$ python foo.py --help 
usage: foo.py [-h] [-v] 

optional arguments: 
    -h, --help  show this help message and exit 
    -v, --version show program's version number and exit 

Chcę spersonalizować ten plik pomocy tak, aby był pisany wielkimi literami i zdaniami, a także umieszczał kropki po zdaniach. Innymi słowy, chcę, aby komunikat pomocy był generowany w ten sposób.

$ python foo.py --help 
Usage: foo.py [-h] [-v] 

Optional arguments: 
    -h, --help  Show this help message and exit. 
    -v, --version Show program's version number and exit. 

Jest to coś, co mogę kontrolować za pomocą API argparse. Jeśli tak to jak? Czy możesz podać mały przykład pokazujący, jak to zrobić?

+0

Czy próbowano ustawienie [ 'help'] (https://docs.python.org/3/library/argparse.html# Wsparcie)? – jonrsharpe

+0

Och, widzę - wtedy możesz ustawić 'add_help' na' False' i zrobić to ręcznie. Ale małe litery to konwencja dla tych rzeczy. – jonrsharpe

Odpowiedz

14

Po pierwsze: kapitulacja tych zwrotów leci wbrew konwencjom, a argparse nie jest tak naprawdę narzędziem ułatwiającym zmianę tych łańcuchów. Masz tu trzy różne klasy ciągów znaków: tekst w zestawie z programu do formatowania pomocy, tytuły sekcji i tekst pomocy dla poszczególnych opcji. Wszystkie te struny są lokalnie dostępne; ty może po prostu dostarczyć tłumaczenie "pisane wielką literą" dla wszystkich tych ciągów przez gettext() module support. Powiedziawszy, możesz osiągnąć i zastąpić wszystkie te ciągi, jeśli jesteś wystarczająco zdeterminowany i read the source code a little.

Czynność version zawiera domyślny tekst help, ale można podać własny, ustawiając argument help. To samo dotyczy akcji help; jeśli ustawisz add_help argument do False można dodać, że działania ręcznie:

parser = argparse.ArgumentParser(add_help=False) 

parser.add_argument('-v', '--version', action='version', 
        version='%(prog)s 1.0', help="Show program's version number and exit.") 
parser.add_argument('-h', '--help', action='help', default=argparse.SUPPRESS, 
        help='Show this help message and exit.') 

Dalej komunikat optional arguments to tytuł grupa; każdy parser ma dwie domyślne grupy, jedną dla argumentów pozycyjnych, drugą dla opcji opcjonalnej. Można dotrzeć do nich przez atrybuty _positionals i _optionals, z których oba mają title atrybut:

parser._positionals.title = 'Positional arguments' 
parser._optionals.title = 'Optional arguments' 

ostrzegamy, poprzez dostęp nazwach zaczynających się od znaku podkreślenia jesteś wyruszą w nieudokumentowane prywatnej API modułu, a twój kod może się zepsuć w przyszłych aktualizacjach.

Na koniec, aby zmienić ciąg znaków usage, należy utworzyć podklasę formantu pomocy; zdać podklasę się jako formatter_class argument:

class CapitalisedHelpFormatter(argparse.HelpFormatter): 
    def add_usage(self, usage, actions, groups, prefix=None): 
     if prefix is None: 
      prefix = 'Usage: ' 
     return super(CapitalisedHelpFormatter, self).add_usage(
      usage, actions, groups, prefix) 

parser = argparse.ArgumentParser(formatter_class=CapitalisedHelpFormatter) 

Demo, stawiając je wszystkie razem:

>>> import argparse 
>>> class CapitalisedHelpFormatter(argparse.HelpFormatter): 
...  def add_usage(self, usage, actions, groups, prefix=None): 
...   if prefix is None: 
...    prefix = 'Usage: ' 
...   return super(CapitalisedHelpFormatter, self).add_usage(
...    usage, actions, groups, prefix) 
... 
>>> parser = argparse.ArgumentParser(add_help=False, formatter_class=CapitalisedHelpFormatter) 
>>> parser._positionals.title = 'Positional arguments' 
>>> parser._optionals.title = 'Optional arguments' 
>>> parser.add_argument('-v', '--version', action='version', 
...      version='%(prog)s 1.0', help="Show program's version number and exit.") 
_VersionAction(option_strings=['-v', '--version'], dest='version', nargs=0, const=None, default='==SUPPRESS==', type=None, choices=None, help="Show program's version number and exit.", metavar=None) 
>>> parser.add_argument('-h', '--help', action='help', default=argparse.SUPPRESS, 
...      help='Show this help message and exit.') 
_HelpAction(option_strings=['-h', '--help'], dest='help', nargs=0, const=None, default='==SUPPRESS==', type=None, choices=None, help='Show this help message and exit.', metavar=None) 
>>> print(parser.format_help()) 
Usage: [-v] [-h] 

Optional arguments: 
    -v, --version Show program's version number and exit. 
    -h, --help  Show this help message and exit. 
+0

To nadal drukuje "usage:" i "opcjonalne argumenty:" we wszystkich małych literach. Jak mogę wszystko wykorzystać? –

+3

@LoneLearner: w tym momencie musisz zadać sobie pytanie, czy to jest tego warte; te wartości są zakodowane gdzie indziej w bazie kodu. Popatrzę, czy coś da się zrobić, ale prawdopodobnie istnieją ograniczenia. –

2

Martijn ma dać kilka poprawek, które przyszło mi do głowy - dostarczanie parametru help oraz niestandardowa klasa Formatter.

Jedna z częściowych poprawek polega na zmodyfikowaniu ciągu pomocy po utworzeniu argumentu. add_argument tworzy i zwraca obiekt Action zawierający parametry i wartości domyślne. Możesz zapisać link do tego i zmodyfikować Action. Możesz również uzyskać listę tych działań i podjąć odpowiednie działania.

Pozwól mi zilustrować za pomocą prostego parsera z domyślnym pomoc i jednego innego argumentu lista działanie jest:

In [1064]: parser._actions 
Out[1064]: 
[_HelpAction(option_strings=['-h', '--help'], dest='help', nargs=0, const=None, default='==SUPPRESS==', type=None, choices=None, help='show this help message and exit', metavar=None), 
_StoreAction(option_strings=['-f', '--foo'], dest='foo', nargs=None, const=None, default=None, type=None, choices=None, help=None, metavar=None)] 

mogę przeglądać i modyfikować atrybut help któregokolwiek z nich:

In [1065]: parser._actions[0].help 
Out[1065]: 'show this help message and exit' 
In [1066]: parser._actions[0].help='Show this help message and exit.' 

wytwarzania tej pomocy:

In [1067]: parser.parse_args(['-h']) 
usage: ipython3 [-h] [-f FOO]  
optional arguments: 
    -h, --help   Show this help message and exit. 
    -f FOO, --foo FOO 

Używanie parser._actions lista używa "prywatnego" atrybutu, który niektórzy uważają za nierozsądny. Ale w Pythonie, że publiczne/prywatne rozróżnienie nie jest ścisłe i można je zrywać ostrożnie. Martijn robi to, uzyskując dostęp do parser._positionals.title.

Innym sposobem na zmianę tego tytułu grupa jest z grupami niestandardowych argumentów

ogroup=parser.add_argument_group('Correct Optionals Title') 
ogroup.add_argument('-v',...) 
ogroup.add_argument('-h',...)