2011-11-08 24 views
6

Tome el siguiente código bastante estándar:Python optparse, valores predeterminados y opciones explícitas

from optparse import OptionParser       
opts = OptionParser() 
opts.add_option('-f', action="store_true") 
opts.add_option("-x", dest="x", type="int", default=1) 
options, args = opts.parse_args() 

Supongamos que -x y -f son excluyentes entre sí: cuando -x y -f son a la vez presente de forma explícita, se debe informar de un error.

¿Cómo puedo detectar si -x está presente explícitamente? Incluso si no lo es, options enumera el valor predeterminado.

Una forma sería evitar establecer el valor predeterminado que prefiero no hacer, porque --help imprime muy bien los valores predeterminados.

Otra forma sería el registro sys.argv para las instancias de -x, que es un poco incómodo, también, si hay más de un nombre para -x (es decir, un nombre de --long) y hay más de un par de mutuamente excluyentes opciones.

¿Existe una solución elegante para esto?

Respuesta

7

Use argparse. Hay una sección para mutually exclusive groups:

argparse.add_mutually_exclusive_group(required=False)

Create a mutually exclusive group. argparse will make sure that only one of the arguments in the mutually exclusive group was present on the command line:

>>> parser = argparse.ArgumentParser(prog='PROG') 
>>> group = parser.add_mutually_exclusive_group() 
>>> group.add_argument('--foo', action='store_true') 
>>> group.add_argument('--bar', action='store_false') 
>>> parser.parse_args(['--foo']) 
Namespace(bar=True, foo=True) 
>>> parser.parse_args(['--bar']) 
Namespace(bar=False, foo=False) 
>>> parser.parse_args(['--foo', '--bar']) 
usage: PROG [-h] [--foo | --bar] 
PROG: error: argument --bar: not allowed with argument --foo 

optparse es obsoleto de todos modos.

8

Puede lograr esto con optparse usando una devolución de llamada. La construcción de su código:

from optparse import OptionParser 

def set_x(option, opt, value, parser): 
    parser.values.x = value 
    parser.values.x_set_explicitly = True 

opts = OptionParser() 
opts.add_option('-f', action="store_true") 
opts.add_option("-x", dest="x", type="int", default=1, action='callback', 
       callback=set_x) 
options, args = opts.parse_args() 
opts.values.ensure_value('x_set_explicitly', False) 

if options.x_set_explicitly and options.f: 
    opts.error('options -x and -f are mutually exclusive') 

Vamos a llamar a este script op.py por ahora. Si lo hago python op.py -x 1 -f, la respuesta es:

Usage: op.py [options]

op.py: error: options -x and -f are mutually exclusive

Cuestiones relacionadas