web-dev-qa-db-fra.com

Personnaliser le message d'aide argparse

J'ai écrit l'exemple de code suivant pour illustrer mon problème.

import argparse

parser = argparse.ArgumentParser()
parser.add_argument('-v', '--version', action='version',
                    version='%(prog)s 1.0')
parser.parse_args()

Cela produit le message d'aide suivant.

$ python foo.py --help
usage: foo.py [-h] [-v]

optional arguments:
  -h, --help     show this help message and exit
  -v, --version  show program's version number and exit

Je souhaite personnaliser cette sortie d'aide de manière à ce qu'elle capitalise toutes les phrases et phrases et place les points après les phrases. En d'autres termes, je veux que le message d'aide soit généré comme ceci.

$ python foo.py --help
Usage: foo.py [-h] [-v]

Optional arguments:
  -h, --help     Show this help message and exit.
  -v, --version  Show program's version number and exit.

Est-ce quelque chose que je peux contrôler en utilisant l'API argparse. Si c'est le cas, comment? Pourriez-vous s'il vous plaît fournir un petit exemple qui montre comment cela peut être fait?

24
Lone Learner

Tout d'abord: la mise en majuscule de ces phrases va à l'encontre de la convention, et argparse n'est pas vraiment un outil pour vous aider à changer facilement ces chaînes. Vous avez ici trois classes de chaînes différentes: le texte passe-partout du formateur d'aide, les titres des sections et le texte d'aide par option spécifique. Toutes ces chaînes sont localisables; vous pourriez simplement fournir une traduction "en majuscule" pour toutes ces chaînes via le module gettext() . Cela dit, vous pouvez atteindre et remplacer toutes ces chaînes si vous êtes suffisamment déterminé et lisez un peu le code source .

L'action version inclut un texte par défaut help, mais vous pouvez fournir le vôtre en définissant l'argument help. Il en va de même pour l'action help; si vous définissez add_help argument to False vous pouvez ajouter cette action manuellement:

parser = argparse.ArgumentParser(add_help=False)

parser.add_argument('-v', '--version', action='version',
                    version='%(prog)s 1.0', help="Show program's version number and exit.")
parser.add_argument('-h', '--help', action='help', default=argparse.SUPPRESS,
                    help='Show this help message and exit.')

Ensuite, le optional arguments le message est un titre de groupe ; chaque analyseur possède deux groupes par défaut, un pour les arguments positionnels, l'autre pour les arguments facultatifs. Vous pouvez les atteindre par les attributs _positionals et _optionals, qui ont tous deux un attribut title:

parser._positionals.title = 'Positional arguments'
parser._optionals.title = 'Optional arguments'

Soyez averti , en accédant aux noms commençant par un trait de soulignement, vous vous aventurez dans l'API privée non documentée du module, et votre code risque de se casser dans les futures mises à jour.

Enfin, pour modifier la chaîne usage, vous devrez sous-classer le formateur d'aide; passez la sous-classe comme formatter_class argument :

class CapitalisedHelpFormatter(argparse.HelpFormatter):
    def add_usage(self, usage, actions, groups, prefix=None):
        if prefix is None:
            prefix = 'Usage: '
        return super(CapitalisedHelpFormatter, self).add_usage(
            usage, actions, groups, prefix)

parser = argparse.ArgumentParser(formatter_class=CapitalisedHelpFormatter)

Démo, rassemblant tous ces éléments:

>>> import argparse
>>> class CapitalisedHelpFormatter(argparse.HelpFormatter):
...     def add_usage(self, usage, actions, groups, prefix=None):
...         if prefix is None:
...             prefix = 'Usage: '
...         return super(CapitalisedHelpFormatter, self).add_usage(
...             usage, actions, groups, prefix)
...
>>> parser = argparse.ArgumentParser(add_help=False, formatter_class=CapitalisedHelpFormatter)
>>> parser._positionals.title = 'Positional arguments'
>>> parser._optionals.title = 'Optional arguments'
>>> parser.add_argument('-v', '--version', action='version',
...                     version='%(prog)s 1.0', help="Show program's version number and exit.")
_VersionAction(option_strings=['-v', '--version'], dest='version', nargs=0, const=None, default='==SUPPRESS==', type=None, choices=None, help="Show program's version number and exit.", metavar=None)
>>> parser.add_argument('-h', '--help', action='help', default=argparse.SUPPRESS,
...                     help='Show this help message and exit.')
_HelpAction(option_strings=['-h', '--help'], dest='help', nargs=0, const=None, default='==SUPPRESS==', type=None, choices=None, help='Show this help message and exit.', metavar=None)
>>> print(parser.format_help())
Usage: [-v] [-h]

Optional arguments:
  -v, --version  Show program's version number and exit.
  -h, --help     Show this help message and exit.
31
Martijn Pieters

Martijn a donné quelques-unes des corrections qui lui sont venues à l'esprit - la fourniture du paramètre help et une classe de formateur personnalisée.

Un autre correctif partiel consiste à modifier la chaîne d'aide après la création de l'argument. add_argument crée et renvoie un objet Action qui contient les paramètres et les valeurs par défaut. Vous pouvez enregistrer un lien vers cela et modifier le Action. Vous pouvez également obtenir une liste de ces actions et agir en conséquence.

Permettez-moi d'illustrer, pour un analyseur simple avec l'aide par défaut et un autre argument, la liste d'actions est:

In [1064]: parser._actions
Out[1064]: 
[_HelpAction(option_strings=['-h', '--help'], dest='help', nargs=0, const=None, default='==SUPPRESS==', type=None, choices=None, help='show this help message and exit', metavar=None),
 _StoreAction(option_strings=['-f', '--foo'], dest='foo', nargs=None, const=None, default=None, type=None, choices=None, help=None, metavar=None)]

Je peux afficher et modifier l'attribut help de n'importe lequel de ces éléments:

In [1065]: parser._actions[0].help
Out[1065]: 'show this help message and exit'
In [1066]: parser._actions[0].help='Show this help message and exit.'

produire cette aide:

In [1067]: parser.parse_args(['-h'])
usage: ipython3 [-h] [-f FOO]    
optional arguments:
  -h, --help         Show this help message and exit.
  -f FOO, --foo FOO

En utilisant le parser._actions list utilise un attribut 'privé', que certaines personnes considèrent imprudent. Mais en Python cette distinction public/privé n'est pas serrée et peut être brisée avec précaution. Martijn le fait en accédant au parser._positionals.title.

Une autre façon de modifier le titre de ce groupe consiste à utiliser des groupes d'arguments personnalisés

ogroup=parser.add_argument_group('Correct Optionals Title')
ogroup.add_argument('-v',...)
ogroup.add_argument('-h',...)
3
hpaulj