example ejemplo argumentparser python getopt

ejemplo - optparse python 3



¿Procesando múltiples valores para una sola opción usando getopt/optparse? (7)

A pesar de las afirmaciones de los otros comentarios, esto es posible con vainilla optparse, al menos a partir de python 2.7. Solo necesitas usar action = "append". De la docs :

parser.add_option("-t", "--tracks", action="append", type="int")

Si se ve -t3 en la línea de comandos, optparse hace el equivalente de:

options.tracks = [] options.tracks.append(int("3"))

Si, un poco más tarde, se ve --tracks = 4, lo hace:

options.tracks.append(int("4"))

¿Es posible obtener múltiples valores para una opción usando getopt o optparse, como se muestra en el siguiente ejemplo:

./hello_world -c arg1 arg2 arg3 -b arg4 arg5 arg6 arg7

Tenga en cuenta que el número de valores reales para cada opción (-c, -b) podría ser 1 o 100. No quiero usar: ./hello_world -c "arg1 arg2 arg3" -b "arg4 arg5 arg6 arg7"

Me parece que esto puede no ser posible (y quizás en violación de POSIX), corríjame si me equivoco.

He visto ejemplos donde todas las no opciones al final de la línea ( ./hello_world -c arg1 -b arg1 arg2 arg3 ) se pueden recopilar ... pero no para la primera opción múltiple.

Me gustaría que mi aplicación funcionara en una amplia gama de plataformas con diferentes versiones de Python, por lo que no he visto argparser.


Ni getopt ni optparse admiten esto fuera de la caja. Además, en el modo predeterminado (GNU), los argumentos adicionales se tratarán como argumentos intercalados, es decir, estarán disponibles como argumentos sobrantes al final del procesamiento.

La convención sería requerir la mención repetida del mismo argumento, es decir,

./hello_world -c arg1 -c arg2 -c arg3 -b arg4 -b arg5 -b arg6 -b arg7

Esto es apoyado

Si absolutamente quieres que funcione de la manera que especifiques (es decir, tanto -b como -c se extienden hasta el siguiente - argumento o el final de la lista de argumentos), entonces puedes hackear algo junto con optparse. Heredar de OptionParser e invalidar _process_short_opts. Si es una de tus opciones, procesala en la subclase, o reenvía a la clase base.


Otra opción sería definir un separador y procesarlo localmente, como las opciones en el comando de montaje.

Por ejemplo, si puede usarse como separador:

... args, _ = getopt.getopt(sys.argv[1:],''b:'') for flag, arg in args: if flag==''-b'': all_arguments = arg.split('','') ... $ ./test -b opt1,opt2,opt3

Lo mismo para el espacio! Pero entonces sus usuarios tienen que citarlo correctamente.

$ ./test -b ''opt1 opt2 opt3''


Perdón por llegar tarde a la fiesta, pero resolví esto con optparse usando la bandera de nargs.

parser.add_option(''-c'',''--categories'', dest=''Categories'', nargs=4 )

http://docs.python.org/2/library/optparse.html#optparse.Option.nargs

También vale la pena señalar, que argparse (sugerido por unutbu) ahora es parte de la distribución estándar de Python, mientras que optparse está en desuso.


Puede hacer esto con el parámetro nargs en argparse que viene con Python2.7, y descargable here .

Creo que es una de las mejoras agregadas a argparse que no está en optparse . Entonces, desafortunadamente, no creo que haya una buena manera de manejar esto con optparse o getopt (que es aún más antiguo).

Una solución rápida y sucia podría ser renunciar a optparse/getop/argparse y simplemente analizar sys.argv usted mismo.

O, yendo en la dirección opuesta, podría considerar empaquetar una copia congelada de argparse (~ 88K) (renombrado algo como argparse_static ) con su programa, e importarlo de esta manera:

try: import argparse except ImportError: import argparse_static as argparse

De esa manera, el programa usará argparse si está instalado, y usará argparse_static si no lo está. Lo mejor de todo es que no tendrá que volver a escribir tanto código como argparse convierte en estándar.


Sí, se puede hacer con optparse.

Esto es un ejemplo:

./test.py --categories=aaa --categories=bbb --categories ccc arg1 arg2 arg3

que imprime:

arguments: [''arg1'', ''arg2'', ''arg3''] options: {''categories'': [''aaa'', ''bbb'', ''ccc'']}

Ejemplo de trabajo completo a continuación:

#!/usr/bin/env python import os, sys from optparse import OptionParser from optparse import Option, OptionValueError VERSION = ''0.9.4'' class MultipleOption(Option): ACTIONS = Option.ACTIONS + ("extend",) STORE_ACTIONS = Option.STORE_ACTIONS + ("extend",) TYPED_ACTIONS = Option.TYPED_ACTIONS + ("extend",) ALWAYS_TYPED_ACTIONS = Option.ALWAYS_TYPED_ACTIONS + ("extend",) def take_action(self, action, dest, opt, value, values, parser): if action == "extend": values.ensure_value(dest, []).append(value) else: Option.take_action(self, action, dest, opt, value, values, parser) def main(): PROG = os.path.basename(os.path.splitext(__file__)[0]) long_commands = (''categories'') short_commands = {''cat'':''categories''} description = """Just a test""" parser = OptionParser(option_class=MultipleOption, usage=''usage: %prog [OPTIONS] COMMAND [BLOG_FILE]'', version=''%s %s'' % (PROG, VERSION), description=description) parser.add_option(''-c'', ''--categories'', action="extend", type="string", dest=''categories'', metavar=''CATEGORIES'', help=''comma separated list of post categories'') if len(sys.argv) == 1: parser.parse_args([''--help'']) OPTIONS, args = parser.parse_args() print "arguments:", args print "options:", OPTIONS if __name__ == ''__main__'': main()

Más información en http://docs.python.org/library/optparse.html#adding-new-actions


Una más fácil:

make_option( "-c", "--city", dest="cities", action="append", default=[], help="specify cities", )

La acción de anexar es la solución más fácil para este problema.