Hilfe anzeigen Nachricht mit Python argparse wenn Skript ohne Argumente aufgerufen wird

StackOverflow https://stackoverflow.com/questions/4042452

  •  27-09-2019
  •  | 
  •  

Frage

Dies könnte ein einfacher sein. Angenommen, ich ein Programm haben, dass Verwendungen Prozessbefehlszeilenargumente / Optionen argparse. Im Folgenden wird die ‚Hilfe‘ Nachricht drucken:

./myprogram -h

oder:

./myprogram --help

Aber, wenn ich das Skript ohne Argumente auch immer laufen, tut es nichts. Was ich tun möchte, ist die Verwendung Meldung anzuzeigen, wenn es ohne Argumente aufgerufen wird. Wie geht das?

War es hilfreich?

Lösung

Diese Antwort kommt von Steven Bethard auf Google-Gruppen . Ich bin hier reposting, um es für die Menschen leichter zu machen, ohne ein Google-Konto zugreifen.

Sie können das Standardverhalten der error Methode überschreiben:

import argparse
import sys

class MyParser(argparse.ArgumentParser):
    def error(self, message):
        sys.stderr.write('error: %s\n' % message)
        self.print_help()
        sys.exit(2)

parser = MyParser()
parser.add_argument('foo', nargs='+')
args = parser.parse_args()

Beachten Sie, dass die oben genannte Lösung wird die Hilfemeldung drucken, wenn die error Methode ausgelöst. Zum Beispiel wird test.py --blah die Hilfemeldung drucken Auch wenn --blah ist keine gültige Option.

Wenn Sie nur die Hilfemeldung drucken, wenn keine Argumente auf dem gelieferten Kommandozeile, dann vielleicht ist dies immer noch der einfachste Weg:

import argparse
import sys

parser=argparse.ArgumentParser()
parser.add_argument('foo', nargs='+')
if len(sys.argv)==1:
    parser.print_help(sys.stderr)
    sys.exit(1)
args=parser.parse_args()

Beachten Sie, dass parser.print_help() druckt standardmäßig stdout. Als init_js schlägt , Verwendung parser.print_help(sys.stderr) auf stderr drucken.

Andere Tipps

Statt eine Klasse zu schreiben, ein Try / außer kann stattdessen verwendet werden

try:
    options = parser.parse_args()
except:
    parser.print_help()
    sys.exit(0)

Der Vorteil ist, dass der Workflow klarer ist und Sie keine Stub-Klasse benötigen. Der Nachteil ist, dass die erste ‚Nutzung‘ Linie zweimal gedruckt wird.

Dies wird zumindest ein obligatorisches Argument benötigen. Ohne obligatorische Argumente, die Bereitstellung Null args auf der Kommandozeile gültig ist.

Mit argparse Sie tun können:

parser.argparse.ArgumentParser()
#parser.add_args here

#sys.argv includes a list of elements starting with the program
if len(sys.argv) < 2:
    parser.print_usage()
    sys.exit(1)

Wenn Sie Argumente, die für das Skript angegeben werden muss laufen - Mit erforderlich Parameter für ArgumentParser wie unten dargestellt: -

parser.add_argument('--foo', required=True)

parse_args () meldet einen Fehler, wenn das Skript ohne Argumente ausgeführt wird.

Wenn Sie assoziieren Standardfunktionen für (Teil-) Parser, wie erwähnt unter add_subparsers , können Sie einfach fügen Sie es als Standard-Aktion:

parser = argparse.ArgumentParser()
parser.set_defaults(func=lambda x: parser.print_usage())
args = parser.parse_args()
args.func(args)

Fügen Sie die try-except, wenn Sie Ausnahmen erhöhen aufgrund Positions Argumente fehlen.

Werfen meiner Version in den Haufen hier:

import argparse

parser = argparse.ArgumentParser()
args = parser.parse_args()
if not vars(args):
    parser.print_help()
    parser.exit(1)

Sie können die parser.exit bemerken - ich es so, dass in erster Linie, weil es eine Import Linie spart, wenn das der einzige Grund für sys in der Datei ist ...

Die sauberste Lösung wird manuell Standardargument zu übergeben, wenn keine auf der Kommandozeile angegeben wurde:

parser.parse_args(args=None if sys.argv[1:] else ['--help'])

Komplettes Beispiel:

import argparse, sys

parser = argparse.ArgumentParser()
parser.add_argument('--host', default='localhost', help='Host to connect to')
# parse arguments
args = parser.parse_args(args=None if sys.argv[1:] else ['--help'])

# use your args
print("connecting to {}".format(args.host))

Dies druckt vollständige Hilfe (nicht kurz usage), wenn w / o Argumente genannt.

Es gibt ein Paar Einzeiler mit sys.argv[1:] (einem sehr häufigen Python Idiom der Befehlszeilenargumente beziehen, sys.argv[0] das Name des Skripts zu sein), die die Arbeit tun können.

Die erste ist selbsterklärend, sauber und pythonic:

args = parser.parse_args(None if sys.argv[1:] else ['-h'])

Das zweite ist ein wenig hackier. die zuvor bewerteten Tatsache die Kombination, dass eine leere Liste ist False mit dem True == 1 und False == 0 Äquivalenzen Sie diese:

args = parser.parse_args([None, ['-h']][not sys.argv[1:]])

Vielleicht zu viele Klammern, aber ziemlich klar, ob eine frühere Argument Auswahl getroffen wurde.

_, *av = sys.argv
args = parser.parse_args([None, ['-h']][not av])
parser.print_help()
parser.exit()

Die parser.exit Methode akzeptiert auch einen status (Return) und einen message Wert (gehört ein Newline selbst!).

ein opinionated Beispiel, :)

#!/usr/bin/env python3

""" Example argparser based python file
"""

import argparse

ARGP = argparse.ArgumentParser(
    description=__doc__,
    formatter_class=argparse.RawTextHelpFormatter,
)
ARGP.add_argument('--example', action='store_true', help='Example Argument')


def main(argp=None):
    if argp is None:
        argp = ARGP.parse_args()  # pragma: no cover

    if 'soemthing_went_wrong' and not argp.example:
        ARGP.print_help()
        ARGP.exit(status=128, message="\nI just don't know what went wrong, maybe missing --example condition?\n")


if __name__ == '__main__':
    main()  # pragma: no cover

Beispiel aufruft:

$ python3 ~/helloworld.py; echo $?
usage: helloworld.py [-h] [--example]

 Example argparser based python file

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

I just don't know what went wrong, maybe missing --example condition?
128
$ python3 ~/helloworld.py --example; echo $?
0

Stellen Sie Ihre Positionsargumente mit nargs, und prüfen Sie, ob Positions args sind leer.

import argparse
parser = argparse.ArgumentParser()
parser.add_argument('file', nargs='?')
args = parser.parse_args()
if not args.file:
    parser.print_help()

Python nargs

Hier ist eine weitere Möglichkeit, es zu tun, wenn Sie etwas brauchen flexible, wo Sie Hilfe anzeigen möchten, wenn bestimmte params übergeben werden, gar keine oder mehr als 1 widersprüchliche arg:

import argparse
import sys

def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('-d', '--days', required=False,  help="Check mapped inventory that is x days old", default=None)
    parser.add_argument('-e', '--event', required=False, action="store", dest="event_id",
                        help="Check mapped inventory for a specific event", default=None)
    parser.add_argument('-b', '--broker', required=False, action="store", dest="broker_id",
                        help="Check mapped inventory for a broker", default=None)
    parser.add_argument('-k', '--keyword', required=False, action="store", dest="event_keyword",
                        help="Check mapped inventory for a specific event keyword", default=None)
    parser.add_argument('-p', '--product', required=False, action="store", dest="product_id",
                        help="Check mapped inventory for a specific product", default=None)
    parser.add_argument('-m', '--metadata', required=False, action="store", dest="metadata",
                        help="Check mapped inventory for specific metadata, good for debugging past tix", default=None)
    parser.add_argument('-u', '--update', required=False, action="store_true", dest="make_updates",
                        help="Update the event for a product if there is a difference, default No", default=False)
    args = parser.parse_args()

    days = args.days
    event_id = args.event_id
    broker_id = args.broker_id
    event_keyword = args.event_keyword
    product_id = args.product_id
    metadata = args.metadata
    make_updates = args.make_updates

    no_change_counter = 0
    change_counter = 0

    req_arg = bool(days) + bool(event_id) + bool(broker_id) + bool(product_id) + bool(event_keyword) + bool(metadata)
    if not req_arg:
        print("Need to specify days, broker id, event id, event keyword or past tickets full metadata")
        parser.print_help()
        sys.exit()
    elif req_arg != 1:
        print("More than one option specified. Need to specify only one required option")
        parser.print_help()
        sys.exit()

    # Processing logic here ...

Cheers!

Wenn Ihr Befehl ist etwas, wo ein Benutzer benötigt eine Aktion zu wählen, dann verwenden, um eine für beide Seiten exklusive Gruppe mit required = true .

Dies ist eine Art Erweiterung der von pd321 gegebenen Antwort.

import argparse

parser = argparse.ArgumentParser()
group = parser.add_mutually_exclusive_group(required=True)
group.add_argument("--batch", action='store', type=int,  metavar='pay_id')
group.add_argument("--list", action='store_true')
group.add_argument("--all", action='store_true', help='check all payments')

args=parser.parse_args()

if args.batch:
    print('batch {}'.format(args.batch))

if args.list:
    print('list')

if args.all:
    print('all')

Ausgabe:

  

$ python3 a_test.py
  Nutzung: a_test.py [-h] (--batch pay_id | --list | --all)
  a_test.py: Fehler: eines der Argumente --batch --list --alle erforderlich

Dies ist nur die grundlegende Hilfe geben. Und einige der anderen Antworten werden Ihnen die volle Hilfe geben. Aber zumindest die Benutzer wissen, was sie tun können h

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top