2015-12-31 16 views
5

Ich bin daran interessiert, die ArgumentDefaultsHelpFormatter Klassenformatierung von argparse zu verwenden (mein Programm hat mehrere Unterbefehle). Standardmäßig sind die Eingabe- und Ausgabeargumente auf sys.stdin bzw. sys.stdout festgelegt. Allerdings kann die Formatierung für diese beiden Argumente für die Benutzer ein wenig verwirrend sein (zB: ', mode' r 'bei 0x10028e0c0>) Gibt es eine Möglichkeit, das Ausgabeformat für diese beiden Argumente gezielt und einfach zu ändern so etwas wie 'default: STDIN' oder? 'default: STDOUT'Argparse und ArgumentDefaultsHelpFormatter. Formatieren von Standardwerten, wenn sys.stdin/stdout als Standard ausgewählt ist

Danke

import sys 
import argparse 

parser = argparse.ArgumentParser(prog='PROG', 
           formatter_class=argparse.ArgumentDefaultsHelpFormatter) 

parser.add_argument('--infile', 
       '-i', 
       metavar='File', 
       help='The input file/stream.', 
       default=sys.stdin, 
       type=argparse.FileType('r'), 
       required=False) 

parser.add_argument('--outfile', 
       '-o', 
       metavar='File', 
       help='The output file/stream.', 
       default=sys.stdout, 
       type=argparse.FileType('r'), 
       required=False) 

parser.add_argument('--whatever-arg', 
       '-w', 
       type=str, 
       default='any', 
       help='Change something', 
       required=False) 


args = parser.parse_args() 
parser.print_help() 

welche gibt:

usage: PROG [-h] [--infile File] [--outfile File] 
      [--whatever-arg WHATEVER_ARG] 

optional arguments: 
    -h, --help   show this help message and exit 
    --infile File, -i File 
         The input file/stream. (default: <open file '<stdin>', 
         mode 'r' at 0x10028e0c0>) 
    --outfile File, -o File 
         The output file/stream. (default: <open file 
         '<stdout>', mode 'w' at 0x10028e150>) 
    --whatever-arg WHATEVER_ARG, -w WHATEVER_ARG 
         Change something (default: any) 
+0

Wäre es nicht einfacher, den Standardformatierer zu verwenden und die Standardwerte explizit in der Hilfe aufzulisten?Eine andere Möglichkeit ist, 'FileType' zu ​​überspringen und die Dateien später selbst zu öffnen. 'FileType' ist praktisch für kleine Skripte, nicht so gut für große (wo Sie mehr Kontrolle darüber brauchen, wann die Dateien geöffnet sind). – hpaulj

+0

Mein Programm enthält etwa 30 Unterprogramme, die alle ihren eigenen Satz von Argumenten haben. Daher ist es sehr praktisch, die Formatierung mit Standardwerten zu verwenden. Ich kann den FileType überspringen, aber in diesem Fall werde ich nicht von der argparse Dateiprüfung profitieren. – user451460

+0

Dann funktioniert die '_get_help_string' Methode. Das ist alles, was diese Standard-Formatierungsklasse sowieso tut. – hpaulj

Antwort

3

Sie ArgumentDefaultsHelpFormatter können Unterklasse zu tun, was Sie wollen

.
from argparse import ArgumentDefaultsHelpFormatter,RawDescriptionHelpFormatter 

class CustomFormatter(argparse.ArgumentDefaultsHelpFormatter, argparse.RawDescriptionHelpFormatter): 
    def _get_help_string(self, action): 
     help = action.help 
     if '%(default)' not in action.help: 
      if action.default is not argparse.SUPPRESS: 
       defaulting_nargs = [argparse.OPTIONAL, argparse.ZERO_OR_MORE] 
       if action.option_strings or action.nargs in defaulting_nargs: 
        if type(action.default) == type(sys.stdin): 
         print action.default.name 
         help += ' (default: ' + str(action.default.name) + ')' 
        else: 
         help += ' (default: %(default)s)' 
     return help 

parser = argparse.ArgumentParser(prog='PROG', formatter_class=CustomFormatter) 

Ergebnis für mich ist:

optional arguments: 
    -h, --help   show this help message and exit 
    --infile File, -i File 
         The input file/stream. (default: <stdin>) 
    --outfile File, -o File 
         The output file/stream. (default: <stdout>) 
    --whatever-arg WHATEVER_ARG, -w WHATEVER_ARG 
         Change something (default: any) 
+0

Einrücken nach dem 'def 'ist aus. Ansonsten ist das Konzept gültig. – hpaulj

+0

Vielen Dank für Ihre Hilfe. – user451460

2

Wenn Sie default='-' statt sys.stdin geben, würde die Hilfeanzeige

the input file/stream. (default: -) 

sein Das heißt, Hilfe zeigt die Standardzeichenfolge, aber FileType wandelt '-' zu stdin/out.

Wie A.H zeigt, können Sie die _get_help_string Methode anpassen. Es spielt keine Rolle, welche Klasse Sie erben von, da diese Methode zu modifizieren alle ist, dass ADHF tut:

class ArgumentDefaultsHelpFormatter(HelpFormatter): 
    """... 
    """ 
    def _get_help_string(self, action): 
     help = action.help 
     if '%(default)' not in action.help: 
      if action.default is not SUPPRESS: 
       defaulting_nargs = [OPTIONAL, ZERO_OR_MORE] 
       if action.option_strings or action.nargs in defaulting_nargs: 
        help += ' (default: %(default)s)' 
     return help 

Und beachten Sie, dass dies alles Modifikation tut, ist eine Zeichenfolge an den help Parameter hinzufügen - nur die (default: %(default)s)

Das bedeutet, Sie könnten einen ähnlichen Effekt erzielen, indem Sie Ihre eigenen help Zeilen, z

parser.add_argument('--infile', 
       '-i', 
       metavar='File', 
       help='The input file/stream, (default: stdin).', 
       default='-', 
       type=argparse.FileType('r')) 

parser.add_argument('--whatever-arg', 
       '-w', 
       default='any', 
       help='Change something, (default: %(default)s)') 

Mit anderen Worten: es spart Sie (default: %(default)s) für 28 Ihre Argumente eingeben.

Wenn es Ihnen unangenehm ist, die HelpFormatter-Klasse anzupassen (obwohl Entwickler dies empfehlen - mit entsprechenden Vorsichtsmaßnahmen), können Sie Ihr eigenes Setup optimieren. Zum Beispiel einfache Helferfunktion machen, dass die zusätzliche Saite an jede Helpline ergänzt:

def foohelp(astr): 
    return astr + ' (default: %(default)s)' 

arg1 = parser.add_argument('-f','--fooarg', help=foohelp('help string')) 

des Sprechens das Setup programmatisch verändert, ist es erwähnenswert, dass add_argument ein Action Objekt erstellt. Sie können wie hier eine Verknüpfung speichern und Parameter optimieren.

arg1 = parser.add_argument('-f','--fooarg', help='help string') 
print arg1.help 
arg1.help = foohelp(arg1.help) # modify help after creation 
print arg1.help 

Mit 30 Argumenten, die Sie wahrscheinlich eine Menge getan haben Kopie-n-Paste sich oder verschiedene Hilfsfunktionen writen zu definieren, um das Setup zu optimieren. Das Hinzufügen der Standardanzeige ist nur eine weitere dieser Aufgaben. Sie können dies während der Installation tun, oder Sie können es über einen benutzerdefinierten Formatierer tun.

+0

Dies sind auch sehr schöne Lösungen. Vielen dank für Deine Hilfe. – user451460