2016-11-21 1 views
3

Ich benutze argparse und ich habe verschiedene Gruppen, die ihre eigenen Optionen gesetzt haben.Hilfe anpassen zwischen Gruppen in argparse

Jetzt mit der --help Option Ich möchte nicht alle Optionen standardmäßig anzeigen. Nur eine Gruppe von Gruppenoptionen soll für --help angezeigt werden.

Gruppe Andere Optionen sollten auf der Grundlage anderen Hilfeoptionen angezeigt werden, wie --help_1, --help_2:

Zum Beispiel:

--help' to show Group 2 and 3 
--help_1' to show Group 11 and 12 
--help_2' to show Group 22 and 23 

Ich weiß, dass wir die Standard-Option --help bei der Verwendung von deaktivieren können add_help = False aber wie bekomme ich nur ausgewählte gruppenspezifische Hilfe angezeigt.

Wir können die Liste der Gruppen aus dem Parser _action_groups bekommen Attribut, aber sie setzen keine print_help() Option als solche.

Mein Beispielcode:

parser = argparse.ArgumentParser(add_help=False) 

parser.add_argument('--help_a', action='store_true') 
parser.add_argument('--help_b', action='store_true') 

group1 = parser.add_argument_group("Feature 1") 
group1.add_argument('--foo1') 
group2 = parser.add_argument_group("Feature 2") 
group2.add_argument('--foo2') 
group3 = parser.add_argument_group("Feature 3") 
group3.add_argument('--foo3') 

# TODO: --help_a to only print "Feature 1" groups help 
# and --help_b to print Feature 2 and 3's help. 

EDIT: Mit subparser und das Hinzufügen von Parsern (statt Gruppe) wird die oben lösen. Aber Subparser passt in meinem Fall nicht, da ich es immer parsiere, muss ich nur Hilfe anpassen, um angezeigt zu werden.

+0

Warum nicht "weniger" durchgehen? 'python command.py --help | weniger " –

+0

Das scheint in meinem Fall nicht richtig. Ich möchte nicht, dass der externe Benutzer meine API oder das Skript verwendet, um auf seiner Seite zu analysieren. Das Skript sollte es alleine behandeln. – baky

+0

Ich verstehe es nicht. Können Sie weitere Informationen hinzufügen, welche Gruppen Sie verwenden und warum Sie verschiedene Hilfeseiten anzeigen möchten? –

Antwort

1

Hier ist der Brauch format_help Ansatz:

import argparse 

def format_help(self, groups=None): 
    # self == parser 
    formatter = self._get_formatter() 

    # usage 
    formatter.add_usage(self.usage, self._actions, 
         self._mutually_exclusive_groups) 

    # description 
    formatter.add_text(self.description) 

    if groups is None: 
     groups = self._action_groups 

    # positionals, optionals and user-defined groups 
    for action_group in groups: 
     formatter.start_section(action_group.title) 
     formatter.add_text(action_group.description) 
     formatter.add_arguments(action_group._group_actions) 
     formatter.end_section() 

    # epilog 
    formatter.add_text(self.epilog) 

    # determine help from format above 
    return formatter.format_help() 

<your parser> 

args = parser.parse_args() 
# _action_groups[:2] are the default ones 
if args.help_a: 
    print(format_help(parser, [parser._action_groups[2]])) 
    parser.exit() 
if args.help_b: 
    print(format_help(parser, parser._action_groups[3:])) 
    parser.exit() 

Probe läuft

1444:~/mypy$ python stack40718566.py --help_a 
usage: stack40718566.py [-h] [--help_a] [--help_b] [--foo1 FOO1] [--foo2 FOO2] 
         [--foo3 FOO3] 

Feature 1: 
    --foo1 FOO1 

1444:~/mypy$ python stack40718566.py --help_b 
usage: stack40718566.py [-h] [--help_a] [--help_b] [--foo1 FOO1] [--foo2 FOO2] 
         [--foo3 FOO3] 

Feature 2: 
    --foo2 FOO2 

Feature 3: 
    --foo3 FOO3 

Es ist also genau wie der Standard format_help, außer es dauert eine groups Parameter. Es könnte sogar die Standardmethode in einer ArgumentParser Unterklasse ersetzen.

Wir könnten auch eine benutzerdefinierte Help Aktionsklasse erstellen, die sich wie die Standardhilfe verhält, außer dass sie eine Art group_list-Parameter benötigt. Aber diese Post-Parsing-Aktion ist einfacher zu codieren und zu testen.

+0

Danke, ich dachte auch über ähnliche Zeilen, wie in der _ActionGroup-Klasse selbst überschreiben, die als zusätzliche Parameter wie 'help_bucket', was zu verwenden, Bedeutung. Aber dieser wird den Trick machen und ist auch sauberer und einfacher. Eine Sache, obwohl die Verwendung alle Optionen standardmäßig anzeigt, kann dies leicht gelöst werden, indem nur die benötigten Aktionen in add_usage hinzugefügt werden. Danke noch einmal – baky

0

Ich empfehle gegen was Sie versuchen zu tun.

You are solving a problem that isn't yours to solve. Es ist die Aufgabe Ihres Skripts, Nutzungsinformationen zurückzugeben. Es ist nicht dein Problem, wenn das eine Menge Text ist. Was Sie tun könnten, tun Sie: Setzen Sie Argumente in Gruppen, die für den Benutzer sinnvoll sind. Aber die Menge an Text ist kein Problem der Datenstruktur, sondern der Datenpräsentation.

Zweitens würden Sie eine Konvention folgen, die niemand verwendet. Es gibt in der Regel

man command 
command --help 
command subcommand --help 

Alles andere verwirrend Erstbenutzer wäre.

Auch, wenn Sie eine Menge Argument Gruppen eine Person haben müßte immer --help konsultieren, um herauszufinden, welche --help_* sie zum nächsten konsultieren wird. Dies kann frustrierend für Benutzer sein, wenn Sie es einfach in --help sofort präsentieren konnten.

Wenn Sie mehrere Hilfeseiten verwenden, würden Sie verhindern die Wiederverwendung Ihres Hilfetextes. Suche zum Beispiel: Mehrere Seiten können nicht durchsucht werden, ohne manuell zwischen ihnen zu wechseln.

Der richtige Weg zu tun ist Pass Text durch einen Paginator wie less.Dies ermöglicht Benutzern, den Text Seite für Seite zu lesen, Suche durch (Presse /) oder speichern Sie sie in Datei: einige Befehle

command --help | less 

Der Einfachheit halber wie git log, auch zu überprüfen, ob die output is an interactive terminal und automatically pass the output through less. Dies würde bedeuten,

command --help > help.txt 

die Hilfe speichert die Datei, während

command --help 

den Hilfetext in Paginierung zeigt, und durchsucht werden.

Also meine Empfehlung für Sie auf Windows und UNIX ist

import os 
import sys 
import argparse 
import subprocess 


def less(data): 
    if sys.stdout.isatty(): 
     if os.name == 'posix': 
      cmd = "less" 
     elif os.name == 'nt': 
      cmd = "more" 

     process = subprocess.Popen([cmd], stdin=subprocess.PIPE) 

     try: 
      process.stdin.write(data) 
      process.communicate() 
     except IOError: 
      pass 
    else: 
     print data 


class MyArgumentParser(argparse.ArgumentParser): 
    def print_help(self, file=None): 
     less(self.format_help()) 
     self.exit() 


parser = MyArgumentParser(prog='PROG') 
group1 = parser.add_argument_group("Feature 1") 
group1.add_argument('--foo1') 
group2 = parser.add_argument_group("Feature 2") 
group2.add_argument('--foo2') 
group3 = parser.add_argument_group("Feature 3") 
group3.add_argument('--foo3') 
# parse some argument lists 
print parser.parse_args() 
+0

Danke für die ausführliche Antwort. In Bezug auf Ihren obigen Kommentar, in dem erwähnt wird, dass die Leute nicht in der Lage sein werden, in die zu verwendende Hilfe zu schauen, werde ich eine "help_all" -Option hinzufügen, so dass dies kein Problem darstellt. BTW, ich werde immer noch schauen, wenn etwas ähnlich wie meine Frage – baky

+0

@hpaulj Lösung für die gleiche geschrieben haben. Bitte werfen Sie einen Blick auf – baky

Verwandte Themen