2011-12-24 7 views
14

El título casi lo dice todo. Si tengo nargs mayor que 1, ¿hay alguna forma en que pueda establecer restricciones (como choice/type) en los archivos args individuales analizados?Tipo de Python argparse y restricciones de elección con nargs> 1

Este es un código de ejemplo:

parser = argparse.ArgumentParser() 
parser.add_argument('-c', '--credits', nargs=2, 
    help='number of credits required for a subject') 

Para el argumento -c necesito especificar un sujeto y cuántos créditos son obligatorios. El tema debe estar limitado a una lista predefinida de asignaturas, y la cantidad de créditos requeridos debe ser flotante.

Probablemente podría hacer esto con un subparser, pero como ya es parte de un subcomando, no quiero que las cosas se vuelvan más complicadas.

Respuesta

16

Puede validarlo con un custom action:

import argparse 
import collections 


class ValidateCredits(argparse.Action): 
    def __call__(self, parser, args, values, option_string=None): 
     # print '{n} {v} {o}'.format(n=args, v=values, o=option_string) 
     valid_subjects = ('foo', 'bar') 
     subject, credits = values 
     if subject not in valid_subjects: 
      raise ValueError('invalid subject {s!r}'.format(s=subject)) 
     credits = float(credits) 
     Credits = collections.namedtuple('Credits', 'subject required') 
     setattr(args, self.dest, Credits(subject, credits)) 

parser = argparse.ArgumentParser() 
parser.add_argument('-c', '--credits', nargs=2, action=ValidateCredits, 
        help='subject followed by number of credits required', 
        metavar=('SUBJECT', 'CREDITS') 
        ) 
args = parser.parse_args() 
print(args) 
print(args.credits.subject) 
print(args.credits.required) 

Por ejemplo,

% test.py -c foo 2 
Namespace(credits=Credits(subject='foo', required=2.0)) 
foo 
2.0 
% test.py -c baz 2 
ValueError: invalid subject 'baz' 
% test.py -c foo bar 
ValueError: could not convert string to float: bar 
+0

+1 Bien, me preguntaba si esto funcionaría. –

+0

Finalmente me puse a implementar esto, y su solución es buena. ¡Ojalá pudiera darte más votos favorables! ¡Gracias! –

+2

Nota para la posteridad: agregar 'metavar = (" SUBJECT "," CREDITS ")' a la llamada 'add_argument' hará que la ayuda muestre' --credits SUBJECT CREDITS' en lugar de '--credititos CREDITS CREDITS'. – Dougal

-2

supongo que se podría probar esto - en add_argument(), puede especificar un conjunto limitado de entradas con choice = 'xyz' o choice = [esto, que] como se describe aquí: http://docs.python.org/library/argparse.html#choices

parser = argparse.ArgumentParser() 
parser.add_argument('-c', '--credits', choice='abcde', nargs=2, 
    help='number of credits required for a subject') 
Cuestiones relacionadas