Abfrage mit optparser geht nicht

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
horald
User
Beiträge: 14
Registriert: Dienstag 28. April 2020, 09:10

ich möchte gerne mit optparser Übergabeparameter abfragen, daher habe ich folgenden Code erstellt:

Code: Alles auswählen

from optparse import OptionParser

parser = OptionParser()
parser.add_option("-i", "--infile", dest="infile",
      help="read data from Input-File", default="infile.txt")
parser.add_option("-o", "--outfile", dest="outfile",
      help="write data to Output-File", default="outfile.txt")
(options, args) = parser.parse_args()
if len(args) < 1:
    parser.error("incorrect number of arguments ("+str(len(args))+")")
else:   
    # my sourcecode


wenn ich das Programm wie folgt aufrufe, meckert es immer, dass keine Parameter übergeben wurden:

Code: Alles auswählen

python3 myprog.py -i myinputfile.txt
Wenn ich die Helffunktion aufrufen, dann wird dies richtig angezeigt:

Code: Alles auswählen

python3 myprog.py --help

Code: Alles auswählen

Usage: myprog.py [options]

Options:
  -h, --help            show this help message and exit
  -i INFILE, --infile=INFILE
                        read data from Input-File
  -o OUTFILE, --outfile=OUTFILE
                        write data to Output-File
Was mache ich falsch? Danke für einen hilfreichen Tipp.
Benutzeravatar
__blackjack__
User
Beiträge: 14005
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@horald: Die ``if``-Bedingung ist halt falsch wenn Du kein Argument übergeben bekommen willst und das willst Du ja anscheinend nicht und machst Du ja auch nicht. Du übergibst eine Option mit Wert und kein einziges Argument, machst aber eine Prüfung die verlangt, das es mindestens ein Argument geben muss.

Warum `optparse`? Aktueller ist `argparse`.

Edit: Bezüglich der API: Wenn das Programm die Namen von Ein- und Ausgabedatei nicht zwingend braucht und es auch jeweils nur eine Ein- und Ausgabe gibt (und man kein `seek()` braucht), ist es in der Regel flexibler einfach die Standardein- und Ausgabe zu verwenden. Und nur optional Optionen für Dateinamen anzubieten.
“The best book on programming for the layman is »Alice in Wonderland«; but that's because it's the best book on anything for the layman.” — Alan J. Perlis
horald
User
Beiträge: 14
Registriert: Dienstag 28. April 2020, 09:10

Sorry, die Antwort verstehe ich nicht! Ich möchte mindestens ein Argument übergeben, damit das Programm weiterläuft, daher die if-Abfrage. Ich übergebe auch ein Argument, aber in der Argumentenliste wird kein Argument ausgegeben und das verstehe ich nicht. Ich kann es ja mal mit argparse versuchen...
horald
User
Beiträge: 14
Registriert: Dienstag 28. April 2020, 09:10

Ich habe es jetzt mit argparse realisiert und damit funktioniert es:

Code: Alles auswählen

import argparse

parser = argparse.ArgumentParser()
parser.add_argument("-i", "--infile", dest="infile", help="read data from input file")
parser.add_argument("-o", "--outfile", dest="outfile", help="write data to output file")
args = parser.parse_args()

if args.infile==None:
    print("Eingabe-Dateinamen uebergeben!")
elif args.outfile==None:
    print("Ausgabe-Dateinamen uebergeben!")
else:
    print("Prog gestartet...")
    print(args.infile)
    print(args.outfile)
Benutzeravatar
__blackjack__
User
Beiträge: 14005
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@horald: Du wolltest kein Argument haben. Welches sollte das denn gewesen sein? Du hattest zwei *Optionen* definiert, und hast beim Aufruf *eine Option mit Wert* angegeben und *kein* Argument. ``-i dateiname`` ist *eine Option*, den Dateinamen speichert `optparse` in dem `options`-Objekt. Der darf gar nicht in `args` landen, denn wie solltest Du denn dann herausfinden zu welcher Option der gehört oder ob er überhaupt zu einer Option gehört‽

Zum `argparse`-Code: Wenn der Name des Zielattributs sowieso nur der Name der langen Option ist, braucht man den nicht noch einmal extra angeben.

Code: Alles auswählen

    parser = argparse.ArgumentParser()
    parser.add_argument("-i", "--infile", help="read data from input file")
    parser.add_argument("-o", "--outfile", help="write data to output file")
Das ist jetzt aber genau die API die keinen Sinn macht, weil Du hier zwei ”Optionen” hast, die überhaupt gar nicht optional sind, also sind das keine Optionen sondern Argumente. Dann brauchst Du auch keinen Code der prüft ob die angegeben wurden, das macht `argparse` dann schon:

Code: Alles auswählen

#!/usr/bin/env python3
import argparse


def main():
    parser = argparse.ArgumentParser()
    parser.add_argument(
        "input_filename", metavar="INFILE", help="input filename"
    )
    parser.add_argument(
        "output_filename", metavar="OUTFILE", help="output filename"
    )
    args = parser.parse_args()

    print("Prog gestartet...")
    print(args.input_filename)
    print(args.output_filename)


if __name__ == "__main__":
    main()
“The best book on programming for the layman is »Alice in Wonderland«; but that's because it's the best book on anything for the layman.” — Alan J. Perlis
Antworten