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) 

Chcę przekazać dodatkowe argumenty do customAction po uruchomieniu opcji -e, np. instancja innej klasy. Jak mogę to zrobić? Wszystko, co wypróbowałem, uległo erozji.Python argparse niestandardowe akcje z dodatkowymi argumentami przekazanymi

Odpowiedz

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 za przyjemne użycie zamknięcia. –

10

Innym rozwiązaniem jest do uzyskania klasy w oparciu argparse.Action tak:

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) 

Alternatywnie, zasilanie *args i **kwargs przejść przez dodatkowe parametry do konstruktora macierzystego.

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

Tak samo, jak kocham zamknięcia, ta odpowiedź uderza mnie jako czystsze (jeśli bardziej zorientowane obiektowo) rozwiązanie. Każdy, kto tego używa, może rozważyć dodanie argumentów '* args' i' ** kwargs' zamiast wyszczególnienia wszystkich domyślnych argumentów 'Action' w argparse. –

+0

ten przykład potrzebowałem zmienić setattr (args na setattr (przestrzeń nazw, aby to działało – kdubs

Powiązane problemy