2016-08-10 10 views
5

Mam pewne argumenty linii poleceń podzielić na następujące grupy:Python argparse: W jaki sposób mogę osobno pobrać obiekty Namespace dla grup argumentów?

cmdParser = argparse.ArgumentParser() 
cmdParser.add_argument('mainArg') 

groupOne = cmdParser.add_argument_group('group one') 
groupOne.add_argument('-optA') 
groupOne.add_argument('-optB') 

groupTwo = cmdParser.add_argument_group('group two') 
groupTwo.add_argument('-optC') 
groupTwo.add_argument('-optD') 

Jak mogę analizować wyżej, tak że mogę skończyć z trzech różnych obiektów Namespace?

global_args - containing all the arguments not part of any group 
groupOne_args - containing all the arguments in groupOne 
groupTwo_args - containing all the arguments in groupTwo 

Dziękujemy!

+0

Nie sądzę argparse ma tę funkcję. – wim

Odpowiedz

1

można to zrobić w ten sposób:

import argparse 
parser = argparse.ArgumentParser() 

group1 = parser.add_argument_group('group1') 
group1.add_argument('--test1', help="test1") 

group2 = parser.add_argument_group('group2') 
group2.add_argument('--test2', help="test2") 

args = parser.parse_args('--test1 one --test2 two'.split()) 

arg_groups={} 

for group in parser._action_groups: 
    group_dict={a.dest:getattr(args,a.dest,None) for a in group._group_actions} 
    arg_groups[group.title]=argparse.Namespace(**group_dict)) 

To daje normalne args plus słownika arg_groups zawierające nazw dla każdego z dodanych grup.

(Adaptacja this answer)

+0

Schludnie! Przyjąłem tę odpowiedź! – shikhanshu

2

Nic w tym argparse nie zostało zaprojektowane.

Dla tego, co jest warte, parser rozpoczyna się od dwóch grup argumentów, jedna wyświetla jako positionals, a druga jako optionals (nie pamiętam dokładnych tytułów). Tak więc w twoim przykładzie faktycznie będą 4 grupy.

Parser używa tylko grup argumentów podczas formatowania pomocy. Podczas analizowania wszystkie argumenty są umieszczane na liście wzorcowej parser._actions. Podczas analizowania składni parser przepuszcza tylko jeden obiekt przestrzeni nazw.

Można zdefiniować oddzielne analizatory składni, z różnymi zestawami argumentów i wywoływać je za pomocą parse_known_args. Działa to lepiej z argumentami optionals (oznaczonymi) niż z positionals. I odciąga twoją pomoc.

mam zbadane w innych SO pytania nową Namespace klasy, które mogą zagnieżdżać wartości oparte na jakimś przerywanymi dest (nazwy jak group1.optA, group2.optC, etc). Nie pamiętam, czy musiałem dostosować klasy Action, czy też nie.

Podstawowym punktem jest to, że podczas zapisywania wartości do przestrzeni nazw, parser, a właściwie o Action (argument) obiektu robi:

setattr(namespace, dest, value) 

że (i getattr/hasattr) to wszystko, że parser oczekuje z namespace. Domyślna klasa Namespace jest prosta, niewiele więcej niż zwykła podklasa object. Ale może być bardziej wyszukane.

+0

Dzięki za wyjaśnienie szczegółów. Skończyło się na ręcznym grupowaniu atrybutów Namespace, tak jak ich potrzebowałem. Byłby to dobry dodatek do argparse, gdyby mógł pozwolić użytkownikowi na pobieranie opcji według nazwy grupy (np. Użyć pojęcia "grupy", aby wyświetlić nie tylko ekran pomocy). – shikhanshu

Powiązane problemy