358 Stimmen

Wie lassen sich Befehlszeilenargumente am besten auswerten?

Was ist das am einfachsten , am knappsten und die meisten flexibel Methode oder Bibliothek zum Parsen von Python-Befehlszeilenargumenten?

15voto

fulmicoton Punkte 14574

So gut wie jeder benutzt getopt

Hier ist der Beispielcode für das Dokument :

import getopt, sys

def main():
    try:
        opts, args = getopt.getopt(sys.argv[1:], "ho:v", ["help", "output="])
    except getopt.GetoptError:
        # print help information and exit:
        usage()
        sys.exit(2)
    output = None
    verbose = False
    for o, a in opts:
        if o == "-v":
            verbose = True
        if o in ("-h", "--help"):
            usage()
            sys.exit()
        if o in ("-o", "--output"):
            output = a

Kurz gesagt, es funktioniert folgendermaßen.

Es gibt zwei Arten von Optionen. Diejenigen, die Argumente empfangen, und diejenigen, die einfach wie Schalter.

sys.argv ist so ziemlich Ihr char** argv Wie in C überspringen Sie das erste Element, das den Namen Ihres Programms darstellt, und analysieren nur die Argumente: sys.argv[1:]

Getopt.getopt wird es gemäß der von Ihnen im Argument angegebenen Regel analysieren.

"ho:v" beschreibt hier die kurzen Argumente: -ONELETTER . Die : bedeutet, dass -o akzeptiert ein Argument.

Endlich ["help", "output="] beschreibt lange Argumente ( --MORETHANONELETTER ). Die Website = nach output bedeutet wiederum, dass output ein Argument akzeptiert.

Das Ergebnis ist eine Liste von Paaren (Option,Argument)

Wenn eine Option kein Argument akzeptiert (wie --help hier) die arg Teil ist eine leere Zeichenkette. In der Regel wollen Sie dann eine Schleife über diese Liste ziehen und den Optionsnamen wie im Beispiel testen.

Ich hoffe, das hat Ihnen geholfen.

9 Stimmen

Mit der Verwerfung von getopt in neueren Versionen von Python ist diese Antwort nicht mehr aktuell.

1 Stimmen

@shuttle87 Ab python3.7.2, getopt ist noch nicht veraltet Aber seine Dokumentation heißt es, dass es hauptsächlich für Benutzer gedacht ist, die mit der C getopt() Funktion, und erkennt an, dass für andere Nutzer argparse könnte eine bessere Lösung sein, die es ermöglicht, "weniger Code zu schreiben und bessere Hilfe und Fehlermeldungen zu erhalten".

15voto

Simon Hibbs Punkte 5641

Leichtgewichtige Befehlszeilenargumente als Standardwerte

Obwohl argparse ist großartig und ist die richtige Antwort für vollständig dokumentierte Befehlszeilenschalter und fortgeschrittene Funktionen, Sie können Funktionsargumentvorgaben verwenden, um einfache Positionsargumente sehr einfach zu handhaben.

import sys

def get_args(name='default', first='a', second=2):
    return first, int(second)

first, second = get_args(*sys.argv)
print first, second

Das Argument "Name" erfasst den Skriptnamen und wird nicht verwendet. Die Testausgabe sieht wie folgt aus:

> ./test.py
a 2
> ./test.py A
A 2
> ./test.py A 20
A 20

Für einfache Skripte, bei denen ich nur einige Standardwerte benötige, finde ich das völlig ausreichend. Möglicherweise möchten Sie auch einige Typ-Zwang in die Rückgabewerte oder Befehlszeilenwerte werden alle Strings sein.

14voto

Corey Punkte 13790

Verwenden Sie optparse die in der Standardbibliothek enthalten ist. Zum Beispiel:

#!/usr/bin/env python
import optparse

def main():
  p = optparse.OptionParser()
  p.add_option('--person', '-p', default="world")
  options, arguments = p.parse_args()
  print 'Hello %s' % options.person

if __name__ == '__main__':
  main()

Quelle: Python zur Erstellung von UNIX-Befehlszeilen-Tools verwenden

Seit Python 2.7 ist optparse jedoch veraltet, siehe: Warum argparse und nicht optparse verwenden?

7voto

Shadow2531 Punkte 11620

Nur für den Fall, dass Sie dies benötigen, kann dies helfen, wenn Sie greifen Unicode-Argumente unter Win32 (2K, XP usw.):

from ctypes import *

def wmain(argc, argv):
    print argc
    for i in argv:
        print i
    return 0

def startup():
    size = c_int()
    ptr = windll.shell32.CommandLineToArgvW(windll.kernel32.GetCommandLineW(), byref(size))
    ref = c_wchar_p * size.value
    raw = ref.from_address(ptr)
    args = [arg for arg in raw]
    windll.kernel32.LocalFree(ptr)
    exit(wmain(len(args), args))
startup()

0 Stimmen

Ich danke Ihnen. Dieses Skript hat mir geholfen, einige wirklich komplizierte Zitate auszuarbeiten, die ich brauchte, um Startbefehle an GVim zu übergeben.

6voto

QA Collective Punkte 1926

Der Argparse-Code kann länger sein als der eigentliche Implementierungscode!

Das ist ein Problem, das ich bei den meisten populären Optionen für die Analyse von Argumenten sehe: Wenn Ihre Parameter nur bescheiden sind, wird der Code, um sie zu dokumentieren, unverhältnismäßig groß im Vergleich zum Nutzen, den sie bieten.

Ein relativer Neuling auf dem Gebiet des Argumentparsing ist (glaube ich) plac .

Es macht einige anerkannte Kompromisse mit argparse, aber verwendet Inline-Dokumentation und wickelt einfach um main() Typ Funktion Funktion:

def main(excel_file_path: "Path to input training file.",
     excel_sheet_name:"Name of the excel sheet containing training data including columns 'Label' and 'Description'.",
     existing_model_path: "Path to an existing model to refine."=None,
     batch_size_start: "The smallest size of any minibatch."=10.,
     batch_size_stop:  "The largest size of any minibatch."=250.,
     batch_size_step:  "The step for increase in minibatch size."=1.002,
     batch_test_steps: "Flag.  If True, show minibatch steps."=False):
"Train a Spacy (http://spacy.io/) text classification model with gold document and label data until the model nears convergence (LOSS < 0.5)."

    pass # Implementation code goes here!

if __name__ == '__main__':
    import plac; plac.call(main)

1 Stimmen

Hinweis: Die sauberste Verwendung von plac (wie im Beispiel gezeigt) ist nur für Python 3.x geeignet, da sie 3.x Funktionsannotationen verwendet.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X