Suche…


Einführung

Die meisten Befehlszeilentools sind auf Argumente angewiesen, die bei der Ausführung an das Programm übergeben werden. Anstatt zur Eingabe aufzufordern, erwarten diese Programme, dass Daten oder bestimmte Flags (die zu Booleans werden) gesetzt werden. Dies ermöglicht es dem Benutzer und anderen Programmen, die Python-Datei auszuführen, wobei die Daten beim Start übergeben werden. In diesem Abschnitt wird die Implementierung und Verwendung von Befehlszeilenargumenten in Python erläutert und veranschaulicht.

Hallo Welt in Schwierigkeiten

Das folgende Programm sagt dem Benutzer Hallo. Es erfordert ein Positionsargument, den Namen des Benutzers, und die Begrüßung kann auch mitgeteilt werden.

import argparse

parser = argparse.ArgumentParser()

parser.add_argument('name', 
    help='name of user'
)

parser.add_argument('-g', '--greeting', 
    default='Hello',
    help='optional alternate greeting'
)

args = parser.parse_args()

print("{greeting}, {name}!".format(
       greeting=args.greeting,
       name=args.name)
)
$ python hello.py --help
usage: hello.py [-h] [-g GREETING] name

positional arguments:
  name                  name of user

optional arguments:
  -h, --help            show this help message and exit
  -g GREETING, --greeting GREETING
                        optional alternate greeting
$ python hello.py world
Hello, world!
$ python hello.py John -g Howdy
Howdy, John!

Für weitere Details lesen Sie bitte die argparse-Dokumentation .

Grundlegendes Beispiel mit docopt

docopt konvertiert Befehlszeilenargumente auf den Kopf. Statt die Argumente zu analysieren, schreiben Sie einfach die Verwendungszeichenfolge für Ihr Programm, und docopt analysiert die Verwendungszeichenfolge und verwendet sie zum Extrahieren der Befehlszeilenargumente.

"""
Usage:
    script_name.py [-a] [-b] <path>

Options:
    -a            Print all the things.
    -b            Get more bees into the path.
"""
from docopt import docopt


if __name__ == "__main__":
    args = docopt(__doc__)
    import pprint; pprint.pprint(args)

Probeläufe:

$ python script_name.py
Usage:
    script_name.py [-a] [-b] <path>
$ python script_name.py something
{'-a': False,
 '-b': False,
 '<path>': 'something'}
$ python script_name.py something -a
{'-a': True,
 '-b': False,
 '<path>': 'something'}
$ python script_name.py -b something -a
{'-a': True,
 '-b': True,
 '<path>': 'something'}

Setzen Sie sich gegenseitig ausschließende Argumente mit argparse

Wenn zwei oder mehr Argumente sich gegenseitig ausschließen sollen. Sie können die Funktion argparse.ArgumentParser.add_mutually_exclusive_group() . Im folgenden Beispiel können entweder foo oder bar vorhanden sein, jedoch nicht beide gleichzeitig.

import argparse

parser = argparse.ArgumentParser()
group = parser.add_mutually_exclusive_group()
group.add_argument("-f", "--foo")
group.add_argument("-b", "--bar")
args = parser.parse_args()
print "foo = ", args.foo
print "bar = ", args.bar

Wenn Sie versuchen, das Skript --foo --bar Argumente --foo und --bar , beschwert sich das Skript mit der folgenden Meldung.

error: argument -b/--bar: not allowed with argument -f/--foo

Befehlszeilenargumente mit argv verwenden

Wenn ein Python-Skript von der Befehlszeile aus aufgerufen wird, kann der Benutzer zusätzliche Befehlszeilenargumente angeben, die an das Skript übergeben werden. Diese Argumente werden an den Programmierer von der Systemvariablen zur Verfügung sys.argv ( „argv“ ist ein traditioneller Name in den meisten Programmiersprachen verwendet, und es bedeutet „arg UMENT v ector“).

sys.argv ist das erste Element in der Liste sys.argv der Name des Python-Skripts selbst, während die übrigen Elemente die Token sind, die der Benutzer beim Aufrufen des Skripts sys.argv .

# cli.py
import sys
print(sys.argv)

$ python cli.py
=> ['cli.py']

$ python cli.py fizz
=> ['cli.py', 'fizz']

$ python cli.py fizz buzz
=> ['cli.py', 'fizz', 'buzz']

Hier ist ein weiteres Beispiel für die Verwendung von argv . Wir entfernen zunächst das ursprüngliche Element von sys.argv, da es den Namen des Skripts enthält. Dann kombinieren wir den Rest der Argumente in einem einzigen Satz und drucken diesen Satz vor dem Namen des aktuell angemeldeten Benutzers (damit ein Chat-Programm emuliert wird).

import getpass
import sys

words = sys.argv[1:]
sentence = " ".join(words)
print("[%s] %s" % (getpass.getuser(), sentence))

Der Algorithmus, der häufig verwendet wird, wenn eine Anzahl nicht-positioneller Argumente "manuell" analysiert wird, besteht darin, die Liste sys.argv . Eine Möglichkeit ist, die Liste durchzugehen und jedes Element davon zu platzieren:

# reverse and copy sys.argv
argv = reversed(sys.argv)
# extract the first element
arg = argv.pop()
# stop iterating when there's no more args to pop()
while len(argv) > 0:
    if arg in ('-f', '--foo'):
        print('seen foo!')
    elif arg in ('-b', '--bar'):
        print('seen bar!')
    elif arg in ('-a', '--with-arg'):
        arg = arg.pop()
        print('seen value: {}'.format(arg))
    # get the next value
    arg = argv.pop()

Benutzerdefinierte Parser-Fehlernachricht mit Argumenten

Sie können Parser-Fehlermeldungen entsprechend Ihren Skriptanforderungen erstellen. Dies geschieht über die Funktion argparse.ArgumentParser.error . Das folgende Beispiel zeigt, dass das Skript eine Verwendung und eine --foo an stderr --foo wenn --foo wird, aber nicht --bar .

import argparse

parser = argparse.ArgumentParser()
parser.add_argument("-f", "--foo")
parser.add_argument("-b", "--bar")
args = parser.parse_args()
if args.foo and args.bar is None:
    parser.error("--foo requires --bar. You did not specify bar.")

print "foo =", args.foo
print "bar =", args.bar

Angenommen, Ihr Skriptname lautet sample.py, und wir führen python sample.py --foo ds_in_fridge : python sample.py --foo ds_in_fridge

Das Skript wird sich mit folgendem beschweren:

usage: sample.py [-h] [-f FOO] [-b BAR]
sample.py: error: --foo requires --bar. You did not specify bar.

Konzeptionelle Gruppierung von Argumenten mit argparse.add_argument_group ()

Wenn Sie argparse ArgumentParser () erstellen und Ihr Programm mit '-h' ausführen, erhalten Sie eine automatisierte Verwendungsnachricht, in der erläutert wird, mit welchen Argumenten Sie Ihre Software ausführen können. Positionsargumente und bedingte Argumente sind standardmäßig in zwei Kategorien unterteilt. Beispiel: Ein kleines Skript (example.py) und die Ausgabe, wenn Sie python example.py -h ausführen.

import argparse

parser = argparse.ArgumentParser(description='Simple example')
parser.add_argument('name', help='Who to greet', default='World')
parser.add_argument('--bar_this')
parser.add_argument('--bar_that')
parser.add_argument('--foo_this')
parser.add_argument('--foo_that')
args = parser.parse_args()
usage: example.py [-h] [--bar_this BAR_THIS] [--bar_that BAR_THAT]
                        [--foo_this FOO_THIS] [--foo_that FOO_THAT]
                        name

Simple example

positional arguments:
  name                 Who to greet

optional arguments:
  -h, --help           show this help message and exit
  --bar_this BAR_THIS
  --bar_that BAR_THAT
  --foo_this FOO_THIS
  --foo_that FOO_THAT

Es gibt Situationen, in denen Sie Ihre Argumente in weitere konzeptionelle Abschnitte unterteilen möchten, um Ihren Benutzer zu unterstützen. Beispielsweise möchten Sie möglicherweise alle Eingabeoptionen in einer Gruppe und alle Optionen zur Ausgabeformatierung in einer anderen Gruppe haben. Das obige Beispiel kann angepasst werden, um die --foo_* args von den --bar_* args zu trennen.

import argparse

parser = argparse.ArgumentParser(description='Simple example')
parser.add_argument('name', help='Who to greet', default='World')
# Create two argument groups
foo_group = parser.add_argument_group(title='Foo options')
bar_group = parser.add_argument_group(title='Bar options')
# Add arguments to those groups
foo_group.add_argument('--bar_this')
foo_group.add_argument('--bar_that')
bar_group.add_argument('--foo_this')
bar_group.add_argument('--foo_that')
args = parser.parse_args()

Was erzeugt diese Ausgabe, wenn python example.py -h wird:

usage: example.py [-h] [--bar_this BAR_THIS] [--bar_that BAR_THAT]
                        [--foo_this FOO_THIS] [--foo_that FOO_THAT]
                        name

Simple example

positional arguments:
  name                 Who to greet

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

Foo options:
  --bar_this BAR_THIS
  --bar_that BAR_THAT

Bar options:
  --foo_this FOO_THIS
  --foo_that FOO_THAT

Erweitertes Beispiel mit docopt und docopt_dispatch

Wie bei docopt bilden Sie mit [docopt_dispatch] Ihre --help in die Variable __doc__ Ihres Einstiegspunktmoduls. Dort rufen Sie dispatch mit dem doc-String als Argument auf, damit der Parser darüber laufen kann.

Anstatt die Argumente manuell zu handhaben (was normalerweise in einer if / else-Struktur mit hoher Zyklizität endet), überlassen Sie es dem Versand, indem Sie nur angeben, wie Sie die Menge der Argumente behandeln wollen.

Dafür gibt es den dispatch.on Dekorator: Sie geben ihm das Argument oder die Folge von Argumenten, die die Funktion auslösen sollen, und diese Funktion wird mit den übereinstimmenden Werten als Parameter ausgeführt.

"""Run something in development or production mode.

Usage: run.py --development <host> <port>
       run.py --production <host> <port>
       run.py items add <item>
       run.py items delete <item>

"""
from docopt_dispatch import dispatch

@dispatch.on('--development')
def development(host, port, **kwargs):
    print('in *development* mode')

@dispatch.on('--production')
def development(host, port, **kwargs):
    print('in *production* mode')

@dispatch.on('items', 'add')
def items_add(item, **kwargs):
    print('adding item...')

@dispatch.on('items', 'delete')
def items_delete(item, **kwargs):
    print('deleting item...')

if __name__ == '__main__':
    dispatch(__doc__)


Modified text is an extract of the original Stack Overflow Documentation
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow