Explain Codes LogoExplain Codes Logo

Argparse: Way to include default values in '--help'?

python
prompt-engineering
best-practices
functions
Nikita BarsukovbyNikita Barsukov·Nov 21, 2024
TLDR

Easily incorporate default values in argparse help messages by injecting %(default)s into the help parameter of add_argument. This instantly brings to life the default value whenever --help is summoned.

For example:

import argparse parser = argparse.ArgumentParser() # Even if you somehow time-travel to 1020 AD, the default value is still 10. Cool, isn't it? parser.add_argument('--count', type=int, default=10, help='Set the count (default: %(default)s)') args = parser.parse_args()

Just run --help and see how the default of --count is neatly included as part of the descriptor (pretty cool, huh?).

To top it off, bridge the gap between verbosity and clarity by using formatter_class=argparse.ArgumentDefaultsHelpFormatter as you initialize ArgumentParser. Now all options automatically include their default values, how convenient is that?

Using formatter_class for efficient automation

If adding %(default)s isn't filling your thirst for a more advanced parsing, try using the formatter_class argument whenever you're creating your ArgumentParser. This brings the balance between uniformity and automation right to your fingertips.

Unleash the power of ArgumentDefaultsHelpFormatter

argparse provides a class called ArgumentDefaultsHelpFormatter. This is not an ordinary class, it's a special one. Why you ask? It effortlessly appends default values to all your argument's help messages. It's like having your own personal assistant!

parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter) # Ever felt like having a pet? Apparently, Python adopted a size for you. parser.add_argument('--size', type=int, default=1024, help='Define the size') args = parser.parse_args()

Just call on your help and each argument's default will be patiently waiting to say hi.

Want a custom formatter? No problemo!

Subclasses are like your dedicated minions. So if the formatter you're given doesn't float your boat, just radiate some subclassing vibes to create your custom help formatter for more control:

import argparse class CustomHelpFormatter(argparse.ArgumentDefaultsHelpFormatter): def _get_help_string(self, action): help = action.help # Hey, I got your back! I won’t add a default if it is None or False. So chill ;) if '%(default)s' not in action.help: if action.default is not None and action.default is not argparse.SUPPRESS: help += ' (default: %(default)s)' return help parser = argparse.ArgumentParser(formatter_class=CustomHelpFormatter) # Do you like echoes (echo.. echo..)? Set verbosity to your liking! parser.add_argument('--verbosity', type=int, choices=[0, 1, 2], help='Increase output verbosity') args = parser.parse_args()

Having your own subclasses is like going on an adventure with an invisibility cloak. Everything is just cleaner!

Advanced customization using multiple inheritance

In some cases, you might want to combine functionalities of different argparse formatters. A touch of multiple inheritance can be just the spark you need. But tread carefully, we're messing with the non-public APIs. It's like messing with secret family recipes, could be rewarding but also risky.

class HybridFormatter(argparse.ArgumentDefaultsHelpFormatter, argparse.RawTextHelpFormatter): pass

This hybrid approach allows you to enjoy both default values and raw, unaltered help text without battering an eyelash.

Key insights into crafting effective help messages

help parameter is your chance to make it clear and detailed:

  • Be concise: Too many words drown the meaning.
  • Highlight the purpose: Explaining why it needs to be used changes the game.
parser.add_argument('--mode', choices=['safe', 'fast'], default='safe', help="Operating modes: 'safe' for precise results (default), 'fast' for quick but rough results")

This illustrates not just the default but also the subtext behind every option.

Avoiding common pitfalls

Choosing defaults is an art, and you need to consider usual scenarios and potential errors:

  • Set sensible defaults: Defaults that make sense for the most common scenario.
  • Prevent common typos: Limit input to valid options and provide explicit instructions in help.
parser.add_argument('--retry', nargs='?', const=5, type=int, default=3, help='Number of retries on error (default: 3, pass without value for more retries)')

Here, the nargs and const parameters give users the power to quickly switch to a common alternative default if needed.