2014-04-17 31 views
5

Mam kilka skryptów w języku Python, które używają wspólnego kodu do odczytu danych wejściowych i zapisywania plików wyjściowych różnych typów.ArgParse Python Module: Zmień domyślną wartość argumentu dla dziedziczonego argumentu

Są to pliki struktury chemicznej. Niektóre przykładowe typy plików to .smi lub .sdf.

Domyślnie chcę, aby niektóre z tych skryptów wyświetlały dane w formacie "smi", a inne dane wyjściowe w formacie "sdf".

Czy można zastąpić domyślną wartość argumentu odziedziczonego z parsera nadrzędnego?

Na przykład ...

# Inherited code 
filesParser = argparse.ArgumentParser(add_help=False) 
filesParser.add_argument('-o', dest='outformat', default="smi") 

# Script code 
parser = argparse.ArgumentParser(description='inherts from filesParser', parents=[filesParser]) 
parser.add_argument('--foo') 

# Something like... 
# parser.outformat.default = "sdf" 

args = parser.parse_args() 

Pierwszy post więc nadzieję, że moja etykieta jest OK.

Dziękujemy, Dave

Odpowiedz

5

Tak (docs):

>>> parser.parse_args([]) 
Namespace(foo=None, outformat='smi') 
>>> parser.set_defaults(outformat='sdf') 
>>> parser.parse_args([]) 
Namespace(foo=None, outformat='sdf') 
+0

Wielkie dzięki! Rozglądałem się przez chwilę i nie zauważyłem tego. – user3544841

2

set_defaults jest chyba najprostszy fix.

Ale myślę, że warto, wiedząc, że można zmienić domyślne skargi bezpośrednio

filesParser = argparse.ArgumentParser(add_help=False) 
outaction=filesParser.add_argument('-o', dest='outformat', default="smi") 
parser = argparse.ArgumentParser(description='inherts from filesParser', parents=[filesParser]) 
fooaction=parser.add_argument('--foo') 
print fooaction.default 
# None 
print outaction.default 
# 'smi' 
outaction.default='sdf' 
args=parser.parse_args() 
print args 
# Namespace(foo=None, outformat='sdf') 

add_argument zwraca obiekt Action, który zawiera wszystkie informacje, które określono w argumentach. Tutaj zapisuję (linki do) tych akcji w zmiennych outaction i fooaction. outaction.default to domyślna wartość używana przez parse_args.

Po odziedziczonym kodzie prawdopodobnie zapisanie tego linku outaction jest niezręczne (choć można go znaleźć na liście "parser._actions"). Dlatego warto, aby set_defaults wykonała zadanie za Ciebie.

Kod dla set_defaults może być pouczające:

def set_defaults(self, **kwargs): 
    self._defaults.update(kwargs) 

    # if these defaults match any existing arguments, replace 
    # the previous default on the object with the new one 
    for action in self._actions: 
     if action.dest in kwargs: 
      action.default = kwargs[action.dest] 

Najpierw stawia nowe ustawienia domyślne w słowniku parser._defaults, a następnie warunkowo modyfikuje atrybut action.default (zwróć uwagę na przeszukiwanie parser._actions). Musi to zrobić, ponieważ kiedy przychodzi czas na użycie wartości domyślnych, wartość action.default ma pierwszeństwo przed wartością parser._defaults.

Te szczegóły będą bardziej sensowne, jeśli uruchomisz ten kod w interaktywnej powłoce (np. Ipython) i możesz wydrukować obiekty action i parser. Obowiązują zwykle przestrogi dotyczące gry z atrybutami "prywatnymi".