2011-12-26 12 views
12
import argparse 

class customAction(argparse.Action): 
    def __call__(self, parser, args, values, option_string=None): 
     setattr(args, self.dest, values) 

parser = argparse.ArgumentParser() 
parser.add_argument('-e', '--example', action=customAction) 

Quiero pasar argumentos adicionales a la acción personalizada cuando se activa la opción -e, p. una instancia de otra clase. ¿Cómo puedo hacer esto? Todo lo que he intentado ha errado.Python argparse acciones personalizadas con argumentos adicionales pasados ​​

Respuesta

31
def make_action(additional_arg): 
    class customAction(argparse.Action): 
     def __call__(self, parser, args, values, option_string=None): 
      print(additional_arg) 
      setattr(args, self.dest, values) 
    return customAction 
#... 
parser.add_argument('-e', '--example', action=make_action('your arg')) 
+8

+1 para un buen uso de un cierre. –

10

Otra solución es derivar la clase base argparse.Action como esto:

class CustomAction(argparse.Action): 
    def __init__(self,option_strings, 
       additional_arg1,additional_arg2, 
       dest=None, 
       nargs=0, 
       default=None, 
       required=False, 
       type=None, 
       metavar=None, 
       help=None): 
     self._a1=additional_arg1 
     self._a2=additional_arg2 
     super(CustomAction, self).__init__(
      option_strings=option_strings, 
      dest=dest, 
      nargs=nargs, 
      default=default, 
      required=required, 
      metavar=metavar, 
      type=type, 
      help=help) 
    def __call__(self, parser, namespace, values, option_string=None): 
     print(self._a1) 
     print(self._a2) 
     setattr(args, self.dest, values) 

#........ 
parser.add_argument('-e', '--example', action=CustomAction, additional_arg1='your arg', additional_arg2=42) 

Alternativamente, el suministro de *args y **kwargs pase a través de los parámetros adicionales al constructor padre.

class CustomAction(argparse.Action): 
    def __init__(self, option_strings, additional_arg1, additional_arg2, 
       *args, **kwargs): 
     self._a1 = additional_arg1 
     self._a2 = additional_arg2 
     super(CustomAction, self).__init__(option_strings=option_strings, 
              *args, **kwargs) 
    def __call__(self, parser, namespace, values, option_string=None): 
     print(self._a1) 
     print(self._a2) 
     setattr(args, self.dest, values) 

#........ 
parser.add_argument('-e', '--example', action=CustomAction, additional_arg1='your arg', additional_arg2=42) 
+0

Por mucho que me gusten los cierres, esta respuesta me parece una solución más limpia (si está más orientada a objetos). Cualquiera que use esto podría considerar agregar '* args' y' ** kwargs' en lugar de enumerar todos los argumentos 'Action' predeterminados de argparse. –

+0

este ejemplo que necesitaba para cambiar setattr (args a setattr (namespace para que funcione) – kdubs

Cuestiones relacionadas