2009-08-11 9 views
5

De acuerdo con PEP 257 la secuencia de comandos de la secuencia de comandos de línea de comandos debe ser su mensaje de uso.¿Cómo cumplir con las cadenas de documentos PEP 257 cuando se usa el módulo optparse de Python?

La cadena de documentación de un script (un programa autónomo) debe ser utilizable como su mensaje de "uso", impresa cuando el guión es invocado con argumentos incorrectos o faltantes (o tal vez con un " -h "opción, para" ayuda "). Tal docstring debe documentar la función del script y la sintaxis de la línea de comandos, las variables de entorno y los archivos. mensajes de uso pueden ser bastante elaborado (varias pantallas completo) y deben ser suficiente para un nuevo usuario al utilizar el comando correctamente, así como una referencia rápida completa a todas las opciones y argumentos para el usuario sofisticado .

Así que mi cadena de documentación sería algo como esto:

 
<tool name> <copyright info> 

Usage: <prog name> [options] [args] 

some text explaining the usage... 

Options: 
    -h, --help show this help message and exit 
    ... 

Ahora quiero usar el módulo optparse. optparse genera las secciones "Opciones" y un "uso" que explica la sintaxis de línea de comandos:

from optparse import OptionParser 

if __name__ == "__main__": 
    parser = OptionParser() 
    (options, args) = parser.parse_args() 

Así que llamar a la secuencia de comandos con los "-h" impresiones de la bandera:

 
Usage: script.py [options] 

Options: 
    -h, --help show this help message and exit 

Esto puede ser modificado según siguiente:

parser = OptionParser(usage="Usage: %prog [options] [args]", 
         description="some text explaining the usage...") 

que resulta en

 
Usage: script.py [options] [args] 

some text explaining the usage... 

Options: 
    -h, --help show this help message and exit 

Pero, ¿cómo puedo usar el docstring aquí? Pasar el docstring ya que el mensaje de uso tiene dos problemas.

  1. optparse anexa "Modo de empleo" a la cadena de documentación si no se inicia con el "Modo de empleo"
  2. El marcador de posición '% PROG' debe ser utilizado en la cadena de documentación

Resultado

De acuerdo con las respuestas, parece que no hay forma de reutilizar la docstring prevista por el módulo optparse. Por lo tanto, la opción restante es analizar manualmente la cadena de documentación y construir OptionParser. (Así que aceptaré la respuesta de S.Loot)

La parte "Uso:" es introducida por el IndentedHelpFormatter que puede ser reemplazado por el parámetro del formateador en OptionParser .__ init __().

Respuesta

4

Opción 1: copiar y pegar. No SECO, pero viable.

Opción 2: analice su propio docstring para quitar el párrafo de la descripción. Siempre es el segundo párrafo, por lo que puedes dividir en '\ n \ n'.

usage, description= __doc__.split('\n\n')[:2] 

Desde optparse genera el uso, puede que no desee suministrar la condena el uso de la misma. Tu versión del uso puede ser incorrecta. Si insistes en proporcionar una cadena de uso al optparse, lo dejaré como ejercicio para que el lector descubra cómo eliminar "Usage: " de la parte frontal de la cadena usage producida anteriormente.

+0

me gusta la segunda solución. No muy limpio, pero inteligente y pragmático. –

+0

Como las líneas en blanco entre los párrafos son el estándar RST, esto ahorra la ejecución de un análisis completo de Docutils en __doc__ y obtiene lo que, por definición, es el resultado esperado. –

+0

Esa podría ser una opción para la descripción. Pero todavía no puedo reutilizar la parte 'uso' y optparse obliga al mensaje a comenzar con "Uso:". – wierob

1

Creo que tenemos que ser razonables con respecto a este consejo de PEP. Creo que está bien dejar el módulo con __doc__, que es la breve descripción que resume el uso prolongado. Pero si usted es perfeccionista:

'''<tool name> 

The full description and usage can be generated by optparse module. 

Description: ... 

''' 

... 

# Generate usage and options using optparse. 
usage, options = ... 

# Modify the docstring on the fly. 
docstring = __doc__.split('\n\n') 
docstring[1:2] = [__license__, usage, options] 
__doc__ = '\n\n'.join(docstring) 
6

me escribió un módulo docopt para hacer exactamente lo que quiere - escribir el uso en mensajes en cadena de documentación y no mojarse. También permite evitar escribir el tedioso código OptionParser, ya que docopt genera el analizador basado en el mensaje de uso.

Compruébelo usted mismo: http://github.com/docopt/docopt

"""Naval Fate. 

Usage: 
    naval_fate.py ship new <name>... 
    naval_fate.py ship [<name>] move <x> <y> [--speed=<kn>] 
    naval_fate.py ship shoot <x> <y> 
    naval_fate.py mine (set|remove) <x> <y> [--moored|--drifting] 
    naval_fate.py -h | --help 
    naval_fate.py --version 

Options: 
    -h --help  Show this screen. 
    --version  Show version. 
    --speed=<kn> Speed in knots [default: 10]. 
    --moored  Moored (anchored) mine. 
    --drifting Drifting mine. 

""" 
from docopt import docopt 


if __name__ == '__main__': 
    arguments = docopt(__doc__, version='Naval Fate 2.0') 
    print(arguments) 
Cuestiones relacionadas