web-dev-qa-db-fra.com

Argparse: Manière d'inclure les valeurs par défaut dans '--help'?

Supposons que j'ai l'argument argparse suivant:

diags.cmdln_parser.add_argument( '--scan-time',
                     action  = 'store',
                     nargs   = '?',
                     type    = int,
                     default = 5,
                     help    = "Wait SCAN-TIME seconds between status checks.")

Actuellement, --help résultats:

usage: connection_check.py [-h]
                             [--version] [--scan-time [SCAN_TIME]]

          Test the reliability/uptime of a connection.



optional arguments:
-h, --help            show this help message and exit
--version             show program's version number and exit
--scan-time [SCAN_TIME]
                    Wait SCAN-TIME seconds between status checks.

Je préférerais quelque chose comme:

--scan-time [SCAN_TIME]
                    Wait SCAN-TIME seconds between status checks.
                    (Default = 5)

Un coup d'oeil au code du formateur d'aide a révélé des options limitées. Existe-t-il un moyen astucieux d’obtenir argparse d’imprimer la valeur par défaut pour --scan-time d'une manière similaire, ou devrais-je simplement sous-classer le formateur help?

255
JS.

Utilisez le argparse.ArgumentDefaultsHelpFormatter _ formateur :

parser = argparse.ArgumentParser(
    # ... other options ...
    formatter_class=argparse.ArgumentDefaultsHelpFormatter)

Pour citer la documentation:

L'autre classe de formateur disponible, ArgumentDefaultsHelpFormatter, ajoutera des informations sur la valeur par défaut de chacun des arguments.

Notez que cela ne s'applique qu'aux arguments pour lesquels du texte d'aide est défini ; sans valeur help pour un argument, il est inutile d'ajouter des informations à.

La sortie exacte de votre option de temps d'analyse devient alors:

  --scan-time [SCAN_TIME]
                        Wait SCAN-TIME seconds between status checks.
                        (default: 5)
381
Martijn Pieters

Ajoutez '%(default)' au paramètre help pour contrôler ce qui est affiché.

parser.add_argument("--type", default="toto", choices=["toto","titi"],
                              help = "type (default: %(default)s)")
162
polux.moon

Classe d'emballage

C’est l’approche la plus fiable et DRY que j’ai trouvée jusqu’à présent pour montrer les valeurs par défaut et utiliser un autre formateur tel que argparse.RawTextHelpFormatter à la fois:

#!/usr/bin/env python3

import argparse

class ArgumentParserWithDefaults(argparse.ArgumentParser):
    def add_argument(self, *args, help=None, default=None, **kwargs):
        if help is not None:
            kwargs['help'] = help
        if default is not None and args[0] != '-h':
            kwargs['default'] = default
            if help is not None:
                kwargs['help'] += ' Default: {}'.format(default)
        super().add_argument(*args, **kwargs)

parser = ArgumentParserWithDefaults(
    formatter_class=argparse.RawTextHelpFormatter
)
parser.add_argument('-a', default=13, help='''my help
for a''')
parser.add_argument('-b', default=42, help='''my help
for b''')
parser.add_argument('--no-default', help='''my help
for no-default''')
parser.add_argument('--no-help', default=101)

parser.print_help()
print()
print(parser.parse_args())

Sortie:

usage: main.py [-h] [-a A] [-b B] [--no-default NO_DEFAULT]
               [--no-help NO_HELP]

optional arguments:
  -h, --help            show this help message and exit
  -a A                  my help
                        for a Default: 13
  -b B                  my help
                        for b Default: 42
  --no-default NO_DEFAULT
                        my help
                        for no-default
  --no-help NO_HELP

Namespace(a=13, b=42, no_default=None, no_help=101)

ArgumentDefaultsHelpFormatter + RawTextHelpFormatter héritage multiple

L'héritage multiple fonctionne simplement, mais cela ne semble pas être une API publique:

#!/usr/bin/env python3

import argparse

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

parser = argparse.ArgumentParser(
    formatter_class=RawTextArgumentDefaultsHelpFormatter
)
parser.add_argument('-a', default=13, help='''my help
for a''')
parser.add_argument('-b', default=42, help='''my help
for b''')
parser.print_help()

Sortie:

usage: a.py [-h] [-a A] [-b B]

optional arguments:
  -h, --help  show this help message and exit
  -a A        my help
              for a (default: 13)
  -b B        my help
              for b (default: 42)

Cela fonctionne simplement parce que, comme nous pouvons le voir trivialement à partir des sources https://github.com/python/cpython/blob/v3.6.5/Lib/argparse.py#L648 que:

  • RawTextHelpFormatter implémente _split_lines
  • ArgumentDefaultsHelpFormatter implémente _get_help_string

on peut donc deviner qu’ils vont bien travailler ensemble.

Cependant, cela ne semble pas être une API publique, pas plus que les méthodes de formatter_class, je ne pense donc pas qu’il existe actuellement une API publique. argparse docstring dit:

Toutes les autres classes de ce module sont considérées comme des détails d'implémentation. (Notez également que HelpFormatter et RawDescriptionHelpFormatter ne sont considérés comme publics que comme noms d'objet - l'API des objets du formateur est toujours considérée comme un détail d'implémentation.)

Voir aussi: personnaliser le message d'aide argparse

Testé sur Python 3.6.5.