python3 - python argparse argumentparser()
Python argparse: ¿Cómo insertar una nueva línea en el texto de ayuda? (5)
Intente usar RawTextHelpFormatter
:
from argparse import RawTextHelpFormatter
parser = ArgumentParser(description=''test'', formatter_class=RawTextHelpFormatter)
Estoy usando argparse
en Python 2.7 para analizar las opciones de entrada. Una de mis opciones es una opción múltiple. Quiero hacer una lista en su texto de ayuda, por ejemplo
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()
Sin embargo, argparse
todas las nuevas líneas y espacios consecutivos. El resultado parece
~/Downloads:52$ python2.7 x.py -h usage: x.py [-h] [-g {a,b,g,d,e}] test optional arguments: -h, --help show this help message and exit -g {a,b,g,d,e} Some option, where a = alpha b = beta g = gamma d = delta e = epsilon
¿Cómo insertar nuevas líneas en el texto de ayuda?
Me he enfrentado a un problema similar (Python 2.7.6). He intentado dividir la sección de descripción en varias líneas usando RawTextHelpFormatter
:
parser = ArgumentParser(description="""First paragraph
Second paragraph
Third paragraph""",
usage=''%(prog)s [OPTIONS]'',
formatter_class=RawTextHelpFormatter)
options = parser.parse_args()
Y consiguió:
usage: play-with-argparse.py [OPTIONS] First paragraph Second paragraph Third paragraph optional arguments: -h, --help show this help message and exit
Así que RawTextHelpFormatter
no es una solución. Debido a que imprime la descripción tal como aparece en el código fuente, conserva todos los caracteres de espacio en blanco (quiero mantener pestañas adicionales en mi código fuente para facilitar la lectura, pero no quiero imprimirlas todas. El formateador en bruto no encaja en la línea cuando está demasiado largo, más de 80 caracteres por ejemplo).
Gracias a @Anton que inspiró la dirección correcta above . Pero esa solución necesita una ligera modificación para formatear la sección de descripción .
De todos modos, se necesita un formateador personalizado. HelpFormatter
clase existente de HelpFormatter
y _fill_text
método _fill_text
como este
import textwrap as _textwrap
class MultilineFormatter(argparse.HelpFormatter):
def _fill_text(self, text, width, indent):
text = self._whitespace_matcher.sub('' '', text).strip()
paragraphs = text.split(''|n '')
multiline_text = ''''
for paragraph in paragraphs:
formatted_paragraph = _textwrap.fill(paragraph, width, initial_indent=indent, subsequent_indent=indent) + ''/n/n''
multiline_text = multiline_text + formatted_paragraph
return multiline_text
Compare con el código fuente original que viene del módulo argparse :
def _fill_text(self, text, width, indent):
text = self._whitespace_matcher.sub('' '', text).strip()
return _textwrap.fill(text, width, initial_indent=indent,
subsequent_indent=indent)
En el código original se está envolviendo toda la descripción. En el formateador personalizado anterior, todo el texto se divide en varios fragmentos, y cada uno de ellos tiene un formato independiente.
Así que con la ayuda de un formateador personalizado:
parser = ArgumentParser(description= """First paragraph
|n
Second paragraph
|n
Third paragraph""",
usage=''%(prog)s [OPTIONS]'',
formatter_class=MultilineFormatter)
options = parser.parse_args()
la salida es:
usage: play-with-argparse.py [OPTIONS] First paragraph Second paragraph Third paragraph optional arguments: -h, --help show this help message and exit
Otra forma fácil de hacerlo es incluir textwrap .
Por ejemplo,
import argparse, textwrap
parser = argparse.ArgumentParser(description=''some information'',
usage=''use "python %(prog)s --help" for more information'',
formatter_class=argparse.RawTextHelpFormatter)
parser.add_argument(''--argument'', default=somedefault, type=sometype,
help= textwrap.dedent(''''''/
First line
Second line
More lines ... ''''''))
De esta manera, podemos evitar el espacio vacío largo delante de cada línea de salida.
usage: use "python your_python_program.py --help" for more information
Prepare input file
optional arguments:
-h, --help show this help message and exit
--argument ARGUMENT
First line
Second line
More lines ...
Quería tener ambos saltos de línea manuales en el texto de la descripción y el ajuste automático del mismo; pero ninguna de las sugerencias aquí funcionó para mí, así que terminé modificando la clase de SmartFormatter dada en las respuestas aquí; A pesar de los problemas con los nombres de los métodos argparse que no son una API pública, esto es lo que tengo (como un archivo llamado test.py
):
import argparse
from argparse import RawDescriptionHelpFormatter
# call with: python test.py -h
class SmartDescriptionFormatter(argparse.RawDescriptionHelpFormatter):
#def _split_lines(self, text, width): # RawTextHelpFormatter, although function name might change depending on Python
def _fill_text(self, text, width, indent): # RawDescriptionHelpFormatter, although function name might change depending on Python
#print("splot",text)
if text.startswith(''R|''):
paragraphs = text[2:].splitlines()
rebroken = [argparse._textwrap.wrap(tpar, width) for tpar in paragraphs]
#print(rebroken)
rebrokenstr = []
for tlinearr in rebroken:
if (len(tlinearr) == 0):
rebrokenstr.append("")
else:
for tlinepiece in tlinearr:
rebrokenstr.append(tlinepiece)
#print(rebrokenstr)
return ''/n''.join(rebrokenstr) #(argparse._textwrap.wrap(text[2:], width))
# this is the RawTextHelpFormatter._split_lines
#return argparse.HelpFormatter._split_lines(self, text, width)
return argparse.RawDescriptionHelpFormatter._fill_text(self, text, width, indent)
parser = argparse.ArgumentParser(formatter_class=SmartDescriptionFormatter, description="""R|Blahbla bla blah blahh/blahbla (bla blah-blabla) a blahblah bl a blaha-blah .blah blah
Blah blah bla blahblah, bla blahblah blah blah bl blblah bl blahb; blah bl blah bl bl a blah, bla blahb bl:
blah blahblah blah bl blah blahblah""")
options = parser.parse_args()
Así es como funciona en 2.7 y 3.4:
$ python test.py -h
usage: test.py [-h]
Blahbla bla blah blahh/blahbla (bla blah-blabla) a blahblah bl a blaha-blah
.blah blah
Blah blah bla blahblah, bla blahblah blah blah bl blblah bl blahb; blah bl
blah bl bl a blah, bla blahb bl:
blah blahblah blah bl blah blahblah
optional arguments:
-h, --help show this help message and exit
Si solo desea anular la opción, no debe usar RawTextHelpFormatter
. En su lugar, subclasifique el HelpFormatter
y proporcione una introducción especial para las opciones que deben manejarse "en bruto" (uso "R|rest of help"
):
import argparse
class SmartFormatter(argparse.HelpFormatter):
def _split_lines(self, text, width):
if text.startswith(''R|''):
return text[2:].splitlines()
# this is the RawTextHelpFormatter._split_lines
return argparse.HelpFormatter._split_lines(self, text, width)
Y úsalo:
from argparse import ArgumentParser
parser = ArgumentParser(description=''test'', formatter_class=SmartFormatter)
parser.add_argument(''-g'', choices=[''a'', ''b'', ''g'', ''d'', ''e''], default=''a'',
help="R|Some option, where/n"
" a = alpha/n"
" b = beta/n"
" g = gamma/n"
" d = delta/n"
" e = epsilon")
parser.parse_args()
Cualquier otra llamada a .add_argument()
donde la ayuda no comienza con R|
Será envuelto como de costumbre.
Esto es parte de mis mejoras en argparse . El SmartFormatter completo también admite agregar los valores predeterminados a todas las opciones, y la entrada en bruto de la descripción de las utilidades. La versión completa tiene su propio método _split_lines
, de modo que se conserva cualquier formato realizado a, por ejemplo, las cadenas de versión:
parser.add_argument(''--version'', ''-v'', action="version",
version="version.../n 42!")