Argparse: arguments requis listés sous "arguments optionnels"?

J'utilise le code simple suivant pour analyser certains arguments; notez que l'un d'entre eux est requis. Malheureusement, lorsque l'utilisateur exécute le script sans fournir l'argument, le texte d'utilisation/aide affiché n'indique pas qu'il existe un argument non facultatif, ce que je trouve très déroutant. Comment puis-je obtenir python pour indiquer qu'un argument n'est pas facultatif?

Voici le code:

import argparse
if __name__ == '__main__':
    parser = argparse.ArgumentParser(
        description='Foo')
    parser.add_argument('-i','--input', help='Input file name', required=True)
    parser.add_argument('-o','--output', help='Output file name', default="stdout")
    args = parser.parse_args()
    print ("Input file: %s" % args.input )
    print ("Output file: %s" % args.output )

Lors de l'exécution du code ci-dessus sans fournir l'argument requis, j'obtiens ce qui suit sortie:

usage: foo.py [-h] -i INPUT [-o OUTPUT]

Foo

optional arguments:
    -h, --help            show this help message and exit
    -i INPUT, --input INPUT
                          Input file name
    -o OUTPUT, --output OUTPUT
                          Output file name
124
demandé sur A-B-B 2014-06-12 13:09:13

3 réponses

Paramètres commençant par - ou -- sont généralement considérés comme facultatifs. Tous les autres paramètres sont des paramètres positionnels et en tant que tels requis par la conception (comme les arguments de fonction positionnelle). Il est possible d'exiger des arguments optionnels, mais c'est un peu contre leur conception. Comme ils font toujours partie des arguments non positionnels, ils seront toujours listés sous l'en-tête confus "arguments optionnels" même s'ils sont requis. Les crochets manquants dans la partie Utilisation cependant montrer qu'ils sont en effet nécessaires.

Voir aussi la documentation :

En général, le module argparse suppose que des drapeaux comme -f et --bar indiquent des arguments optionnels, qui peuvent toujours être omis sur la ligne de commande.

Remarque: les options requises sont généralement considérées comme étant de mauvaise forme car les utilisateurs s'attendent à ce que les options soient facultatives et doivent donc être évitées lorsque cela est possible.

Cela étant dit, les en-têtes "positionnel les arguments" et "arguments optionnels" dans l'aide sont générés par deux argument groupes dont les arguments sont automatiquement séparés en. Maintenant, vous pouvez "pirater" et changer le nom des optionnels, mais une solution beaucoup plus élégante serait de créer un autre groupe pour les " arguments nommés requis "(ou tout ce que vous voulez les appeler):

parser = argparse.ArgumentParser(description='Foo')
parser.add_argument('-o', '--output', help='Output file name', default='stdout')
requiredNamed = parser.add_argument_group('required named arguments')
requiredNamed.add_argument('-i', '--input', help='Input file name', required=True)
parser.parse_args(['-h'])
usage: [-h] [-o OUTPUT] -i INPUT

Foo

optional arguments:
  -h, --help            show this help message and exit
  -o OUTPUT, --output OUTPUT
                        Output file name

required named arguments:
  -i INPUT, --input INPUT
                        Input file name
181
répondu poke 2016-10-05 06:53:48

Comme je préfère lister les arguments requis avant optionnel, je le pirate via:

    parser = argparse.ArgumentParser()
    parser._action_groups.pop()
    required = parser.add_argument_group('required arguments')
    optional = parser.add_argument_group('optional arguments')
    required.add_argument('--required_arg')
    optional.add_argument('--optional_arg')
    return parser.parse_args()

Et ceci produit:

usage: main.py [-h] [--required_arg REQUIRED_ARG]
               [--optional_arg OPTIONAL_ARG]

required arguments:
  --required_arg REQUIRED_ARG

optional arguments:
  --optional_arg OPTIONAL_ARG

Je peux vivre sans que 'help' apparaisse dans le groupe d'arguments optionnels.

32
répondu Karl Rosaen 2017-01-19 16:35:19

Bâtiment hors de @ Karl Rosaen

parser = argparse.ArgumentParser()
optional = parser._action_groups.pop() # Edited this line
required = parser.add_argument_group('required arguments')
# remove this line: optional = parser...
required.add_argument('--required_arg')
optional.add_argument('--optional_arg')
parser._action_groups.append(optional) # added this line
return parser.parse_args()

Et ceci produit:

usage: main.py [-h] [--required_arg REQUIRED_ARG]
           [--optional_arg OPTIONAL_ARG]

required arguments:
  --required_arg REQUIRED_ARG

optional arguments:
  -h, --help                    show this help message and exit
  --optional_arg OPTIONAL_ARG
18
répondu RalphyZ 2017-04-17 17:45:37