argparse Problem

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
mhard666
User
Beiträge: 8
Registriert: Dienstag 22. September 2020, 13:14

Hallo miteinander,

ich befasse mich gerade mal wieder mit meinen "alten" Projekten und verzweifle an meiner Implementierung des Commandline Parsers. Benutzt wird argparse mit Python 3.7.6 64 Bit auf Windows (Mac und Linux).
Eigentlich soll es gar nicht weiter schlimm sein. Ich will mein Python3 Script mit und ohne Parameter starten können. Das funktionier leider nur bedingt oder gar nicht und ich finde den Fehler nicht.

Zuerst mal das Script (commandline.py):

Code: Alles auswählen

#!/usr/bin/env python3

import sys
import argparse

class CommandLineException(BaseException):
    pass

class CommandLine():
    '''
    Klasse zum Speichern und auswerten der Commandline Parameters
    '''
    def __init__(self):
        self._parser = self.__create_parser()
        self._namespace = None

    def __create_parser(self):
        '''
        Kommandozeilenparser erstellen
        '''
        parser = argparse.ArgumentParser(description='rico...')

        parser.add_argument('--debug', '-d', action='store_true', help='Enable debug mode...')
        parser.add_argument('--version', '-v', action='version', version= f"{parser.prog} version 1.0.0", help='Versionsinfo zum Script ausgeben...')
        return parser

    def parse_params(self, args):
        '''
        Parsen der Befehlszeilenparameter starten. Bei Fehler wird eine CommandLineException
        geworfen.
        '''

        # self._namespace = self._parser.parse_args(args)
        # Abfangen des vorzeitigen Beendens des Scripts, wenn Hilfe oder Version ausgegeben wird
        try:
            self._namespace = self._parser.parse_args(args)
        except SystemExit:
            raise CommandLineException

if __name__ == '__main__':
    o = CommandLine()
    try:
        o.parse_params(sys.argv)
    except CommandLineException:
        print("fehler")
Wenn ich das Script mit den Optionen -h bzw. --help oder -v bzw. --version aufrufe, wird Hilfetext oder Version ausgegeben und das Script beendet. Normal. Lasse ich die Parameter weg, erhalte ich folgende Fehlermeldung:

Code: Alles auswählen

usage: commandline.py [-h] [--debug] [--version]
commandline.py: error: unrecognized arguments: c:/Users/irgendwo/.../commandline.py
fehler
Das Gleiche, wenn ich das Script mit der Option --debug aufrufe.

Vielleicht sehe ich den Wald vor lauter Bäumen nicht, aber ich bin langsam am Verzweifeln... Es muss doch möglich sein die Parameter korrekt zu parsen und wenn keine Parameter übergeben wurden, das zu übergehen.
Kann mir bitte jemand auf die Sprünge helfen? Vielen Dank.

VG mhard666.
__deets__
User
Beiträge: 14494
Registriert: Mittwoch 14. Oktober 2015, 14:29

Ein schoenes Beispiel fuer eine komplett ueberfluessige Klasse, die eigentlich eine Funktion sein sollte. Und ueberbordende Fehlerbehandlung. Zusammengedampft sieht das so aus:

Code: Alles auswählen

#!/usr/bin/env python3
import argparse


def parse_params():
    parser = argparse.ArgumentParser(description='rico...')

    parser.add_argument('--debug', '-d', action='store_true', help='Enable debug mode...')
    parser.add_argument('--version', '-v', action='version', version= f"{parser.prog} version 1.0.0", help='Versionsinfo zum Script ausgeben...')

    return parser.parse_args()

if __name__ == '__main__':
    parse_params()
Was dein eigentliches Problem angeht: statt wie ich hier implizit die Argumente aus sys zu benutzen (das Verhalten von parse_args, wenn man *kein* Argument angibt), machst du das selbst. Das ist ueberfluessig (es ist dazu gedacht, wenn die Kommandozeilenargumente irgendwo anders herkommen), und was dann passiert, ist simpel: sys.argv enthaelt eben auch als 0-tes Argument den Namen des Skriptes. Den nutzt du dann implizit als Argument, was du gar nicht willst. sys.argv[1:] waere also "richtig" - aber eben einfach nix tun ist am richtigsten am sein.
mhard666
User
Beiträge: 8
Registriert: Dienstag 22. September 2020, 13:14

Hi __deets__,

Danke, genau das wars...
Den Code habe ich vor über zwei Jahren mal fabriziert und will jetzt daran mal wieder etwas machen. Das ganze rührt aus einem alten Python2 Projekt, das ich nach Python3 umschreiben wollte, worüber ich damals abgestorben bin...
Es waren noch andere Fehler drin, weshalb .parse_args() oder .parse_args(sys.argv[1:]) auch Fehler geworfen haben. Ich habs dann dummerweise nicht nochmal geprüft.

VG mhard666
Antworten