Python argparse: How can I get namespace objects for argument groups separately?

I have command line arguments classified into groups as follows:

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') 

How can I parse the above so that I end up with three different namespace objects?

 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 

Thanks!

+5
source share
2 answers

you can do it like this:

 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)) 

This will give you normal args as well as dictionary arg_groups containing namespaces for each of the added groups.

(adapted from this answer )

+1
source

Nothing in argparse is meant for this.

For what it's worth, parser starts with two groups of arguments, one of which is displayed as positionals , and the other as optionals (I forget the exact headers). So in your example there will actually be 4 groups.

The parser only uses argument groups when formatting help. For parsing, all arguments are placed in the main parser._actions list. And during parsing, the parser skips only one namespace object.

You can define individual parsers with different sets of arguments and call each one with parse_known_args . This works better with optionals arguments (marked) than with positionals . And it fragments your help.

I have studied in other SO questions a new Namespace class that could insert values ​​based on some point dest (names like group1.optA , group2.optC , etc.). I don’t remember whether I need to configure Action classes or not.

The main point is that when you save the value in the namespace, the parser or actually the Action object (argument) does:

 setattr(namespace, dest, value) 

This (and getattr / hasattr) is all that the Namespace parser expects. By default, the Namespace class is simple, slightly larger than a simple subclass of object . But it can be more complicated.

+2
source

All Articles