2016-05-07 13 views
4

Mit Python argaparse „choices“ Standard Hilfe sieht wie folgt aus:Gibt es eine saubere Möglichkeit, eine Ein-Zeilen-Hilfe pro Auswahl für Argarse-Entscheidungen zu schreiben?

>>> parser.add_argument('move', choices=['rock', 'paper', 'scissors']) 

positional arguments: 
    {rock,paper,scissors} 

Welche funktioniert, wenn es offensichtlich ist, wie man holen, aber nicht so groß, wenn jede Wahl eine eigene Mini-Hilfe braucht.

Gibt es eine Möglichkeit einer Online-Hilfe pro Wahl in eine saubere Art und Weise, etwas in dieser Richtung zu schreiben:

parser.add_argument("action", 
        choices=[ 
         ["status", help="Shows current status of sys"], 
         ["load", help="Load data in DB"], 
         ["dump", help="Dump data to csv"], 
        ], 
+0

nicht über argparse wissen nicht, aber ich bezweifle, dass unterstützt werden würde. Es gibt andere Module zur Argumentverarbeitung. Ich mag http://docopt.org/ zum Beispiel. Anstatt die Hilfemeldung aus den angegebenen Argumenten zu erstellen, geben Sie die Hilfemeldung an und dokumentieren, wie Sie die Befehlszeile parsen. –

+3

warum nicht einfach "subparsers" hinzufügen wenn wir 'git' zum Beispiel nehmen, können Sie tun, ' git --help' und 'git commit --help'. Subparser wird Ihnen erlauben, dies zu tun – Urban48

+0

Kann nicht helfen, http://docopt.org zu empfehlen - es ist eine Milliarde Mal besser als ArgParse jemals hoffen kann. – cat

Antwort

2

argparse dieses Format nicht unterstützen. Hier ist meine Lösung. Es ist nicht nett, aber es funktioniert.

from argparse import ArgumentParser, RawTextHelpFormatter 

choices_helper = { "status": "Shows current status of sys", 
        "load": "Load data in DB", 
        "dump": "Dump data to csv"} 

parser = ArgumentParser(description='test', formatter_class=RawTextHelpFormatter)  
parser.add_argument("action", 
        choices=choices_helper, 
        help='\n'.join("{}: {}".format(key, value) for key, value in choices_helper.iteritems())) 

Try Sub-commands(subparsers) zu verwenden ist die bessere Idee.

+1

'argparse unterstützt dies nicht 'Und deshalb ist ArgParse lahm :) kann nicht einmal GNU-Stil' --Hilfe' Bildschirme damit :( – cat

+1

In Ihrer Argumentdefinition können Sie '' selects = choices_helper' verwenden. Es wird die Wörterbuchschlüssel als die Wahlen verwenden, nicht müssen eine Liste bilden. Ich denke, dass Ihre Annäherung zum hübschen Drucken eines Wörterbuchs groß ist. Es macht viel Sinn, die Hilfe so anzupassen. – hpaulj

+0

thanks @hpaulj! Ich werde prüfen es und redigiere meine Antwort. – qvpham

0

@ julivco Antwort erzeugt diese Hilfe:

In [20]: parser.print_help() 
usage: ipython3 [-h] {load,status,dump} 

test 

positional arguments: 
    {load,status,dump} load: Load data in DB 
         status: Shows current status of sys 
         dump: Dump data to csv 

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

Die argparse Umgang mit choices bewusst einfach ist. Es testet mit value in choices und durchläuft es, um die {...}-Zeichenfolge zu erstellen. Es gibt Fehler/Probleme bei der Verbesserung der String-Formatierung, aber niemand hat nach dieser Art von Hilfeformatierung gefragt/vorgeschlagen.

====================

Hier ist eine benutzerdefinierte Aktion Unterklasse. Es verhält sich wie die übliche store, aber leiht Hilfe Formatierungsideen aus der subparser Action-Klasse. Es erwartet choices ein Wörterbuch (das leicht in eine Liste von Listen oder Tupeln geändert werden könnte).

class NewAction(argparse._StoreAction): 
    class _ChoicesPseudoAction(argparse.Action): 
     # from _SubParsersAction 
     def __init__(self, name, aliases, help): 
      metavar = dest = name 
      if aliases: 
       metavar += ' (%s)' % ', '.join(aliases) 
      sup = super(NewAction._ChoicesPseudoAction, self) 
      sup.__init__(option_strings=[], dest=dest, help=help, 
         metavar=metavar) 

    def make_help(self): 
     # build list used for help display 
     self._choices_actions = []  
     for key in self.choices:   
      help = choice_dict[key] 
      choice_action = self._ChoicesPseudoAction(key, [], help) 
      self._choices_actions.append(choice_action) 

    def _get_subactions(self): 
     # called by HelpFormater 
     return self._choices_actions 

choice_dict = { "status": "Shows current status of sys", 
      "load": "Load data in DB", 
      "dump": "Dump data to csv"} 

parser = argparse.ArgumentParser() 
a = parser.add_argument('--foo', action=NewAction, choices=choice_dict, help='choices help') 
a.make_help() 

parser.print_help() 
print(parser.parse_args('--foo status'.split())) 
print(parser.parse_args()) 

Ausgabe wie folgt aussieht:

2028:~/mypy$ python3 stack37094448.py --foo test 
usage: stack37094448.py [-h] [--foo {load,dump,status}] 

optional arguments: 
    -h, --help   show this help message and exit 
    --foo {load,dump,status} 
         choices help 
    load    Load data in DB 
    dump    Dump data to csv 
    status    Shows current status of sys 
Namespace(foo='status') 
usage: stack37094448.py [-h] [--foo {load,dump,status}] 
stack37094448.py: error: argument --foo: invalid choice: 'test' (choose from 'load', 'dump', 'status') 
Verwandte Themen