Yes (docs):
>>> parser.parse_args([])
Namespace(foo=None, outformat='smi')
>>> parser.set_defaults(outformat='sdf')
>>> parser.parse_args([])
Namespace(foo=None, outformat='sdf')
Question
I have a bunch of Python scripts that use common code for reading input and writing output files of different types.
These are chemical structure files. Some example file types would be .smi or .sdf.
By default, I want some of these scripts to output data in the "smi" file format, and others to output data in the "sdf" format.
Is it possible to override the default value of an argument inherited from a parent parser?
For example...
# 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()
First post so hope my etiquette is OK.
Many thanks, Dave
Solution
Yes (docs):
>>> parser.parse_args([])
Namespace(foo=None, outformat='smi')
>>> parser.set_defaults(outformat='sdf')
>>> parser.parse_args([])
Namespace(foo=None, outformat='sdf')
OTHER TIPS
set_defaults
is probably the easiest fix.
But I think it is worth while knowing that you can change the default of an Action directly
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
returns an Action
object, which contains all the information that you specified in the arguments. Here I save (links to) those Actions in variables outaction
and fooaction
. outaction.default
is the default value that parse_args
uses.
With your inherited code it probably is awkward to save that outaction
link (though it is possible to find it in 'parser._actions' list). So it makes sense to let set_defaults
do the job for you.
The code for set_defaults
may be instructive:
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]
First it puts the new defaults in the parser._defaults
dictionary, and then it conditionally modifies the action.default
attribute (note the search of parser._actions
). It has to do both, because when it comes time to use the defaults, the action.default
value has priority over the parser._defaults
value.
These details will make more sense if you run this code in an interactive shell (e.g. Ipython) and can print the action
and parser
objects. The usual cautions about playing with 'private' attributes apply.