argparse was designed around objects. Besides a few constants and utility functions, these are all class definitions. The documentation focuses on the use, not the structure of the class. But it can help to understand it.
parser = argparse.ArgumentParser(...)
creates a parser object.
arg1 = parser.add_argument(...)
creates an argparse.Action object (subclass) and adds it to several parser attributes (lists). Usually we ignore the fact that the method returns this Action object, but sometimes I find it useful. And when I create a parser in an interactive shell, I see this action.
args = parser.parse_args()
launches another method and returns a namespace object ( argparse.Namespace class).
Group methods and subparameters also create and return objects (groups, actions, and / or parsers).
The ArgumentParser method takes the parents parameter, where the value is a list of parser objects.
WITH
parsera = argparse.ArgumentParser(parents=[parserb])
during the creation of parsera actions and groups in parserb copied to parsera . Thus, parsera recognizes all the arguments parserb does. I recommend you check it out.
But there are several qualifications. Copy is a link. That is, parsera gets a pointer to every action defined in parserb . Sometimes this creates problems (I wonβt go into it now). And one or the other should have add_help=False . Usually, the action is added to the parser at creation. But if parserb also helps, there will be a conflict (duplication) that needs to be resolved.
But parents cannot be used if parsera was created independently of parserb . There is no existing mechanism for adding actions from parserb . Maybe you can create a new parser with both parents
parserc = argparse.ArgumentParser(parents=[parsera, parserb])
Perhaps I could write a function that would add arguments from parserb to parsera , borrowing ideas from a method that implements parents . But I have to know how to resolve conflicts.
Take a look at argparse._ActionsContainer._add_container_actions to see how the Actions are copies from parent to parser . Something that can be confusing is that each action is part of a group (user-defined or one of the two default groups (see Help)) in addition to parser .
Another possibility is to use
[argsA, extrasA] = parserA.parse_known_args() [argsB, extrasB] = parserB.parse_known_args()
In addition, each parser processes the arguments that it knows about, and returns the others in the extras list.
If parsers are not designed for this kind of integration, there will be jagged edges with that kind of integration. It may be easier to deal with those who are facing Arnial's approach, which should include defining common arguments in your own methods. Others like to put argument parameters in some kind of database (list, dictionary, etc.) and build a parser from them. You can wrap the creation of the parser with as many layers of the template as possible.