Pregunta

Estoy haciendo un script bastante simple que toma los siguientes parámetros:

-p --port integer, optional, default 5050
-f --fork boolean, optional, default False
action string, required, needs to be either start or stop

He intentado implementar esto en Argparse, pero no está imprimiendo ayuda cuando no se proporciona una cadena de acción, solo está fallando como feo:

usage: __init__.py [-h] [-p PORT] [-f] {start,stop}
__init__.py: error: argument action: invalid choice: '__init__.py' (choose from 'start', 'stop')

Incluso cuando paso "inicio" o "parar", falla con el mismo mensaje. Aquí está mi código:

parser = argparse.ArgumentParser(description="Start or stop the server.",
    epilog="If you don't know what you're doing, run. Run for your life.\n")
parser.add_argument("-p", "--port", type=int, nargs=1, default=5050,
    dest="port", help="The port to run the server on.")
parser.add_argument("-f", "--fork", action="store_true", default=False,
    dest="fork", help="Fork to background? Default is false.")
parser.add_argument("action", type=str, choices=("start","stop"), help="Whether to 'start' or 'stop' the server.")

¿Qué estoy haciendo mal aquí? Ojalá mis intenciones sean bastante claras de mi código.

¿Fue útil?

Solución

¿Qué versión de Python estás usando? Cuando ejecuto su código con 2.7.1 funciona bien.

$ ./t stop
$ ./t start
$ ./t -f start
$ ./t -f stop
$ ./t -f
usage: someprog [-h] [-p PORT] [-f] {start,stop}
someprog: error: too few arguments
$ ./t -f -p 8080
usage: someprog [-h] [-p PORT] [-f] {start,stop}
someprog: error: too few arguments
$ ./t -f -p 8080 start

Un consejo, si especifica 'prog' en el ctor, puede anularlo usando en eso.py como nombre de archivo

parser = argparse.ArgumentParser(
    prog="someprog",
    description="Start or stop the server.",
    epilog="If you don't know what you're doing, run. Run for your life.\n"
)

También eso es Impresión de uso, pero no la larga ayuda ... podrías hacer algo como esto para hacer las cosas un poco más obvias ...

try:
    parser.parse_args()
except Exception e:
    print "************************"
    parser.print_help()
    print "************************"

Otros consejos

Cuando se suministran argumentos no válidos, el módulo argparse está diseñado para imprimir un mensaje de uso y una descripción del problema y luego salir, que es precisamente lo que está sucediendo en su ejemplo.

Si desea que imprima un mensaje de ayuda, deberá manejar este caso usted mismo. Por ejemplo, este código imprimirá el mensaje de ayuda en caso de que no se proporcione ninguna acción:

parser = argparse.ArgumentParser(description="Start or stop the server.",
    epilog="If you don't know what you're doing, run. Run for your life.\n",
    prog="myserver")
parser.add_argument("-p", "--port", type=int, nargs=1, default=5050,
    dest="port", help="The port to run the server on.")
parser.add_argument("-f", "--fork", action="store_true", default=False,
    dest="fork", help="Fork to background? Default is false.")
parser.add_argument("action", nargs="?", type=str, choices=("start","stop"),
    help="Whether to 'start' or 'stop' the server.")

args = parser.parse_args()
if args.action is None:
    parser.print_help()
    sys.exit(1)

Si ejecuto esto sin acción, obtengo:

$ python s.py
usage: myserver [-h] [-p PORT] [-f] [{start,stop}]

Start or stop the server.

positional arguments:
  {start,stop}          Whether to 'start' or 'stop' the server.

optional arguments:
  -h, --help            show this help message and exit
  -p PORT, --port PORT  The port to run the server on.
  -f, --fork            Fork to background? Default is false.

If you don't know what you're doing, run. Run for your life.

Sin embargo, si ejecuto esto con una acción inválida, o un argumento no válido, entonces vuelve al comportamiento previsto del módulo Argparse:

 $ python s.py not_valid
usage: myserver [-h] [-p PORT] [-f] [{start,stop}]
myserver: error: argument action: invalid choice: 'not_valid' (choose from 'start', 'stop')
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top