2011-12-26 7 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) 

Voglio passare argomenti aggiuntivi a customAction quando l'opzione -e viene attivata, ad es. un'istanza di un'altra classe. Come posso fare questo? Tutto ciò che ho provato è andato in errore.Python argparse azioni personalizzate con argomenti aggiuntivi passati

risposta

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 per un buon uso di una chiusura. –

10

Un'altra soluzione è quella di derivare la classe basata argparse.Action simili:

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) 

alternativa, fornitura *args e **kwargs di passare attraverso i parametri aggiuntivi al costruttore genitore.

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

Per quanto ami le chiusure, questa risposta mi sembra una soluzione più pulita (se più orientata agli oggetti). Chiunque usi questo potrebbe prendere in considerazione l'aggiunta di '* args' e' ** kwargs' invece di elencare tutti gli argomenti 'Action' di argparse di default. –

+0

questo esempio ho avuto bisogno di cambiare setattr (args a setattr (namespace per farlo funzionare – kdubs