I wrote the other day about an irritatingly incompatible change in Python 3.14's argparse , where if you deferred setting a default value until later, certain argparse things would now error out. In a comment, Ian Z aka nobrowser asked (in part):
Setting the default right in the
add_argumentcall has always seemed more natural to me. Do you have a case where it is not possible or just inconvenient to do this?
Some of my usage of
set_defaults
is historical and I might do it differently today; in today's Python, setting default values in the
add_argument
call is clearly the accepted and expected style. However, I feel that using
set_defaults
for some or all settings can be a clearer choice if a bunch of default values are clearly related to each other. By setting related default values together, you give future readers visibility into what all of the defaults are, in one place, without forcing them to read the code and pick out all of the 'default=' arguments in
add_argument
calls.
In my view this is especially useful for quick views to remind yourself of what the code's default behavior is. Yes, you can run '--help' (if it prints default values, perhaps with
ArgumentDefaultsHelpFormatter
), but that tells you a lot of additional things beyond the defaults. How much this matters depends on how many arguments you have and how they manipulate their destinations (which isn't always simple). Some of my programs are definitely ones where the default values belong with argument, in
add_argument
, but others have enough that I feel that
set_defaults
is perfectly fine and sometimes easier to deal with.
Using
set_defaults
also puts the name of the option and its default value next to each other, as an assignment. In an
add_argument
call they're split across two keywords:
p.add_argument("--whatever", dest="whatever",
action="store_true",
default=False,
help="Don't do whatever.")
# Compare to:
p.set_defaults(whatever=False, ...)
To read the add_argument() you (I) have to combine 'dest="whatever"' with 'default=False' to get to 'whatever is False by default'. By contrast, that's right there in the
set_defaults
.
(Looking back and forth between various programs actually makes me feel I haven't been using
set_defaults
as much as I probably should. Putting the default value into each new
add_argument
call is the easy way as my programs evolve, but maybe I want to go back more often and set all of them in one block once enough arguments have accumulated.)
Sidebar: A slightly tricky destination manipulation
Consider the following code (which is a version of something I've done in some of my programs):
p.add_argument("--no-whatever", dest="whatever",
action="store_false",
default=True,
help="Don't do whatever.")
This is a perfectly reasonable way to turn off something but it's a little bit confusing to read 'default=True' in the context of setting up the '--no-whatever' argument. In my view this sort of thing is clearer in
set_defaults
, where you aren't distracted by other things and it's clearer that the default value of 'whatever' is True (on).
(This trick also causes
ArgumentDefaultsHelpFormatter
to report the misleading '(default: True)' for '--no-whatever'.)