Używam argparse
w Pythonie 2.7 do analizowania opcji wprowadzania. Jedną z moich opcji jest wielokrotny wybór. Chcę zrobić listę w tekście pomocy, np
from argparse import ArgumentParser
parser = ArgumentParser(description='test')
parser.add_argument('-g', choices=['a', 'b', 'g', 'd', 'e'], default='a',
help="Some option, where\n"
" a = alpha\n"
" b = beta\n"
" g = gamma\n"
" d = delta\n"
" e = epsilon")
parser.parse_args()
argparse
Usuwa jednak wszystkie znaki nowej linii i kolejne spacje. Wynik wygląda jak
~ / Pobrane: 52 $ python2.7 x.py -h użycie: x.py [-h] [-g {a, b, g, d, e}] test opcjonalne argumenty: -h, --help pokaż ten komunikat pomocy i wyjdź -g {a, b, g, d, e} Pewna opcja, gdzie a = alfa b = beta g = gamma d = delta e = epsilon
Jak wstawić znaki nowej linii w tekście pomocy?
argparse
interpretera, więc przełączenie na"""..."""
nie pomoże.Odpowiedzi:
Spróbuj użyć
RawTextHelpFormatter
:źródło
Only the name of this class is considered a public API. All the methods provided by the class are considered an implementation detail.
więc prawdopodobnie nie jest to świetny pomysł, chociaż może nie mieć to znaczenia, ponieważ 2.7 ma być ostatnim pythonem w wersji 2.x i od tego czasu oczekuje się refaktoryzacji wielu rzeczy dla wersji 3.x. W rzeczywistości używam 2.6 zargparse
zainstalowanym przez,easy_install
więc sama dokumentacja może być nieaktualna.RawDescriptionHelpFormatter
który działa tylko na opis i epilog, a nie na tekst pomocy.RawTextHelpFormatter
wiodącymi i końcowymi znakami nowej linii są usuwane. Aby obejść ten problem, możesz po prostu dodać dwie lub więcej kolejnych linii; wszystkie oprócz jednej nowej linii przetrwają.class Formatter( argparse.ArgumentDefaultsHelpFormatter, argparse.RawDescriptionHelpFormatter): pass
I wtedyformatter_class=Formatter
.Jeśli chcesz tylko zastąpić jedną opcję, nie powinieneś jej używać
RawTextHelpFormatter
. Zamiast tego podklasujHelpFormatter
i zapewnij specjalne wprowadzenie dla opcji, które powinny być obsługiwane jako „surowe” (używam"R|rest of help"
):I użyj tego:
Wszelkie inne połączenia z
.add_argument()
miejscem, w którym pomoc się nie zaczyna,R|
będą pakowane normalnie.Jest to część moich ulepszeń dotyczących argparse . Pełny SmartFormatter obsługuje także dodawanie wartości domyślnych do wszystkich opcji i nieprzetworzone wprowadzanie opisu narzędzi. Pełna wersja ma własną
_split_lines
metodę, dzięki czemu zachowane jest formatowanie np. Ciągów wersji:źródło
parser.add_argument('-v', '--version', action='version',version=get_version_str())
Czy można to rozszerzyć na tę sprawę?_split_lines
i zachowuje podziały wierszy (nie trzeba podawać „R |” na początku, jeśli chcesz tę opcję, załataj_VersionAction.__call__
metodę_VersionAction.__call__
tym, że prawdopodobnie wolałbym, abyparser.exit(message=version)
zamiast używać sformatowanej wersji. Czy jest jednak jakiś sposób, aby to zrobić bez wydawania poprawionej kopii argparse?__call__
na_VersionAction
wykonującargparse._VersionAction.__call__ = smart_version
po zdefiniowaniudef smart_version(self, parser, namespace, values, option_string=None): ...
Innym łatwym sposobem na to jest zawijanie tekstu .
Na przykład,
W ten sposób możemy uniknąć długiej pustej przestrzeni przed każdą linią wyjściową.
źródło
Napotkałem podobny problem (Python 2.7.6). Próbowałem rozbić sekcję opisu na kilka wierszy, używając
RawTextHelpFormatter
:I dostał:
To
RawTextHelpFormatter
nie jest rozwiązanie. Ponieważ drukuje opis w takiej postaci, w jakiej pojawia się w kodzie źródłowym, zachowując wszystkie znaki spacji (chcę zachować dodatkowe tabulatory w kodzie źródłowym dla czytelności, ale nie chcę drukować ich wszystkich. Również formatter raw nie zawija wiersza, gdy jest za długa, na przykład ponad 80 znaków).Dzięki @Anton, który zainspirował właściwy kierunek powyżej . Ale to rozwiązanie wymaga niewielkiej modyfikacji, aby sformatować sekcję opisu .
W każdym razie potrzebny jest niestandardowy formatyzator. Rozszerzyłem istniejącą
HelpFormatter
klasę i zastąpiłem_fill_text
taką metodę:Porównaj z oryginalnym kodem źródłowym pochodzącym z modułu argparse :
W oryginalnym kodzie cały opis jest zawijany. W niestandardowym formatorze powyżej cały tekst jest podzielony na kilka części i każdy z nich jest formatowany niezależnie.
Tak więc za pomocą niestandardowego formatyzatora:
dane wyjściowe to:
źródło
HelpFormatter
jest problematyczne, ponieważ programiści argparse gwarantują, że nazwa klasy przetrwa w przyszłych wersjach argparse. Zasadniczo napisali sobie czek in blanco, aby mogli zmienić nazwy metod, jeśli byłoby to dla nich wygodne. To mnie frustruje; przynajmniej mogliby zrobić, to ujawnić kilka metod w API.Chciałem mieć zarówno ręczne podziały wierszy w tekście opisu, jak i automatyczne zawijanie go; ale żadna z sugestii tutaj nie działała dla mnie - więc ostatecznie zmodyfikowałem klasę SmartFormatter podaną w odpowiedziach tutaj; pomimo tego, że nazwy metod argparse nie są publicznymi interfejsami API, oto co mam (jako plik o nazwie
test.py
):Tak to działa w wersjach 2.7 i 3.4:
źródło
Począwszy od SmartFomatter opisanego powyżej, skończyłem na tym rozwiązaniu:
Zauważ, że o dziwo argument formatter_class przekazany do parsera najwyższego poziomu nie jest dziedziczony przez sub_parsers, należy przekazać go ponownie dla każdego utworzonego sub_parser.
źródło
Przedmowa
To pytanie
argparse.RawTextHelpFormatter
jest dla mnie pomocne.Teraz chcę podzielić się, jak korzystać z
argparse
.Wiem, że to nie może być związane z pytaniem,
ale te pytania niepokoiły mnie przez jakiś czas.
Chcę więc podzielić się swoim doświadczeniem, mam nadzieję, że będzie to dla kogoś pomocne.
No to ruszamy.
Moduły stron trzecich
colorama : aby zmienić kolor tekstu:
pip install colorama
Przykład
Gdzie klasa
FormatText
jest następującaźródło