2017-05-10 2 views
1

Au lieu d'avoir un tas de littéraux dispersés à travers des appels à add_argument, comme ceci:Puis-je passer un objet dans argparse.add_argument?

parser.add_argument('--foo', 
        required=False, 
        metavar='bar', 
        type=str, 
        help='help message', 
        default='default') 

parser.add_argument('--foo2', 
        required=False, 
        metavar='bar2', 
        type=str, 
        help='help message', 
        default='default') 

J'espérais que je pourrais créer un conteneur d'abord, puis ajouter tous les arguments dans une boucle.
Quelque chose comme ceci:

for arg in argument_container: 
    parser.add_argument(arg) 

Je ne suis pas assez familier avec la façon dont python accepte ces paramètres pour comprendre si elles peuvent être extraites dehors dans une sorte d'objet littéral comme je veux.

Existe-t-il un moyen d'extraire d'abord tous les paramètres dans un conteneur, puis d'ajouter tous les arguments à la fois dans une boucle, comme indiqué ci-dessus?

+0

Avez-vous essayé de le faire? – JohanL

+0

J'ai essayé de passer dans un dictionnaire, ça ne marche pas. J'ai essayé de créer une sorte de littéral d'objet comme un tuple nommé, cela n'a pas fonctionné. J'ai regardé l'implémentation de add_argument, mais je ne suis toujours pas sûr de ce qui peut être accepté dans la fonction. –

Répondre

1

La plupart des paramètres add_argument sont des mots-clés, qui peuvent être transmis via la syntaxe **kwargs. Par exemple:

In [90]: parser=argparse.ArgumentParser() 
In [91]: adict={"metavar":"bar", "help":"help message", "default":"default"} 
In [92]: a1 = parser.add_argument('--foo', **adict) 
In [93]: a1 
Out[93]: _StoreAction(option_strings=['--foo'], dest='foo', nargs=None, const=None, default='default', type=None, choices=None, help='help message', metavar='bar') 

In [94]: parser.print_help() 
usage: ipython3 [-h] [--foo bar] 

optional arguments: 
    -h, --help show this help message and exit 
    --foo bar help message 

Ici, je crée un petit dictionnaire avec quelques-uns des paramètres, et transmis par ceux **adict.

Je n'ai pas inclus '--foo' dans ce dictionnaire car il s'agit d'un paramètre positionnel. Cela pourrait toujours être assigné à une variable, et passé de cette façon.

J'ai enregistré une référence à l'objet renvoyé par add_argument et l'ai affiché. Il montre comment la plupart des paramètres deviennent des attributs de l'objet Action résultant.


Pour votre deuxième argument:

In [95]: dest = "--foo2" 
In [96]: adict={"metavar":"bar2", "help":"help message2", "default":"default2"} 
In [97]: a2 = parser.add_argument(dest, **adict) 
In [98]: 
In [98]: parser.print_help() 
usage: ipython3 [-h] [--foo bar] [--foo2 bar2] 

optional arguments: 
    -h, --help show this help message and exit 
    --foo bar help message 
    --foo2 bar2 help message2 

Il est évident que cela pourrait être généralisé à travailler avec des listes de dictionnaires, ou avec une fonction qui prend des paramètres, génère les disparus et appelle add_argument de cette façon.

+0

Merci. Je ne lisais pas le dictionnaire en le passant. –

2

Pour obtenir à la fois la *args et **kwargs dans la même liste, vous pouvez les ajouter en tant que parties d'un tuple:

import argparse 

parser = argparse.ArgumentParser(description='Process some strings.') 

args = [(('--foo', '-f'), {'help':'Foo help', 'required':False, 'type':str, 'default':'foo'}), 
     (('--bar', '-b'), {'help':'Bar help', 'required':False, 'type':str, 'default':'bar'})] 

for arg in args: 
    parser.add_argument(*arg[0], **arg[1]) 

parsed_args = parser.parse_args() 

Ainsi, la première partie du tuple est un autre tuple, contenant le nom différent du argument, alors la deuxième partie du tuple (externe) est une dict avec le mot clé arguments.