argparse - Command line option and argument parsing

Este post fue migrado de un blog hecho con Wordpress. Si se ve mal, dejame un comentario y lo arreglo.

Hoy recibí la última edición de Python Module of the Week, un semanal de Doug Hellmann sobre módulos de Python. Leo:

The argparse module was added to Python 2.7 as a replacement

for optparse.

Nunca había usando optparse hasta hace un par de meses y estaba contento de haberlo empezado a usar, ordenaba mis programas de línea de comando con bonitos parámetros. ¿Tengo que aprender otro sistema totalmente nuevo? Veamos.

Esta es una parte de mi programa original:

from optparse import OptionParser

parser = OptionParser(usage="rpcping ip [-p port] [-r rep] [-s size]", version="rpcping 1.0")



parser.add_option("-p", type="int", dest="port", default=PORT)

parser.add_option("-r", type="int", dest="rep", default=REP)

parser.add_option("-s", type="int", dest="size", default=SIZE)

(options, args) = parser.parse_args()



if not args:

    parser.error("se necesita la direccion ip del servidor como argumento posicional.")

else:

    ip = args[0]



if not 1024 < options.port < 65535:

    parser.error("el puerto debe ser mayor a 1024 y menor a 65535.")

else:

    port = options.port



if not 0 < options.rep < 101:

    parser.error("las repeticiones deben ser mayores a 0 y menores a 101.")

else:

    rep = options.rep



if not 0 < options.size < 10001:

    parser.error("el tamaño deben ser mayores a 0 y menores a 10001.")

else:

    size = options.size

Qué tuve que cambiar para que funcione con argparse:

  • Cambiar nombres; optparse por argparse, OptionParser por ArgumentParser, add_option por add_argument.
  • Cambiar el valor del agumento type de string a un tipo de verdad. En mi caso type="int" por type=int.
  • Si tratamos de obtener el resultado del parsing así (options, args) = parser.parse_args(), vamos a tener un error TypeError: 'Namespace' object is not iterable. El nombre result en el nuevo código está asociado a un objeto del tipo Namespace.
  • optparse no trabaja con argumentos obligatorios, por lo que para el argumento ip había tenido que escribir código extra por mi cuenta. En argparse es más simple.

El resultado es:

from argparse import ArgumentParser

parser = ArgumentParser(description="Realiza ping via RPC contra un servidor", version="rpcping 1.0")



parser.add_argument("ip")

parser.add_argument("-p", type=int, dest="port", default=PORT)

parser.add_argument("-r", type=int, dest="rep", default=REP)

parser.add_argument("-s", type=int, dest="size", default=SIZE)

result = parser.parse_args()



ip = result.ip



if not 1024 < result.port < 65535:

    parser.error("el puerto debe ser mayor a 1024 y menor a 65535.")

else:

    port = result.port



if not 0 < result.rep < 101:

    result.error("las repeticiones deben ser mayores a 0 y menores a 101.")

else:

    rep = result.rep



if not 0 < result.size < 10001:

    parser.error("el tamaño deben ser mayores a 0 y menores a 10001.")

else:

    size = result.size

Parece que con poco esfuerzo se puede migrar de optparse a argparse y luego empezar a estudiar las nuevas funcionalidades que incorpora.

The implementation of argparse supports features that would not have been easy to add to optparse, and that would have required backwards-incompatible API changes, so a new module was brought into the library instead. optparse is still supported, but is not likely to receive new features.

Más en: PyMOTW: argparse - Command line option and argument parsing.

Comentarios