Kommandozeileparameter i eie Klasse verbauen

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
Julien456935
User
Beiträge: 19
Registriert: Donnerstag 22. November 2018, 15:26

Hallo Leute,
leider konnte ich folgendes Problem nach stundenlanger Einsicht in Lektüren und Foren noch immer nicht Lösen:
Mein Programm soll eine Liste von Kommandozeilenparameter entgegennehmen mit dehnen ich anschließend arbeiten muss.
Das Ganze habe ich wie folgt geschrieben und funktioniert auch:

import argparse

ap = argparse.ArgumentParser()
ap.add_argument("-i", "--input", type = str,
help = "The input wants the file path in which you saved the csv data!")

ap.add_argument("-o", "--output", type = str,
help = "The output wants the file path in which you want to save the output!")

ap.add_argument("-s", "--sensors", default = [],
help = "Wants the Sensor Ids in form of Integers, separeted with a ,")

ap.add_argument("-r", "--resampling_delta", type = int, default = 600,
help = "Size of resampling time steps in seconds")

ap.add_argument("-w", "--window_smoothing", type = int, default = None,
help = "Size of the Time-Window")

parsed_params = ap.parse_args()
program_params = vars(parsed_params)
print(program_params)

Meine bsp Eingabe lautet: python Assignment_2.py -i test -s 45464
Ausgabe dazu: {'input': 'test', 'output': None, 'sensors': '45464', 'resampling_delta': 600, 'window_smoothing': None}

Mein Problem: ich möchte dem Ganzen etwas Struktur geben und eine Klasse schreiben in der ich meine Parameter für eine weitere Verarbeitung geschützt speichern kann und entnehmen kann. Ein Klasse nur für Parameter. Ohne die ganze Zahle meiner gescheiteten Versuche hier aufzulisten, eine Ungefähre Rohfassung:

class cl_param():
import argparse #import the package for the cl_param
ap = argparse.ArgumentParser() #ap = Arg_Parser from the imported package
ap.add_argument("-i", "--input", type = str,
help = "The input wants the file path in which you saved the csv data!")

ap.add_argument("-o", "--output", type = str,
help = "The output wants the file path in which you want to save the output!")

ap.add_argument("-s", "--sensors", default = [],
help = "Wants the Sensor Ids in form of Integers, separeted with a ,")

ap.add_argument("-r", "--resampling_delta", type = int, default = 600,
help = "Size of resampling time steps in seconds")

ap.add_argument("-w", "--window_smoothing", type = int, default = None,
help = "Size of the Time-Window")

parsed_params = ap.parse_args()
program_params = vars(parsed_params)

print(program_params)

def __init__(self,program_params):
self._input = program_params["input"]
self._output = program_params["output"]
self._sensors = program_params["sensors"]
self._resampling_delta = program_params["resampling_delta"]
self._window_smoothing = program_params["window_smoothing"]

def get_input(self)
return self._input

cl_param.get_input()
Laut meiner momentanen Kenntnissen bewirkt der Unterstrich nach "self." das die variable geschützt ist und aus dem Dictionary "program_params" werden meine Variablen erstellt. Meine Vermutung, eine solche Implementierung funktioniert nicht da das Objekt noch gar nicht erstellt wurde? cl_param.get_input() benötigt ein Argument, keine Ahnung welches? Jemand eine Idee wie man so etwas realisieren könnte?

Wie gesagt mein Ziel ist eine Klasse von der ich meine Kommandozeilenparameter bekomme und verarbeiten kann.
Außerdem möchte ich diese Parameter in anderen Klassen verwenden können, wie folgt müsste das dann ja auch so gehen, bekomme aber keinen Zugriff?

class nächste_Klasse(cl_param):
def __init__(self)
super().__init__()

Ein Dankeschön im voraus!!
__deets__
User
Beiträge: 14539
Registriert: Mittwoch 14. Oktober 2015, 14:29

Bitte verwende die code-Tags, welche dir in dem vollstaendigen Editor angeboten werden, damit man deinen Code auch lesen kann - so gehen leider die Einrueckungen verloren.

Zweitens kannst du auf die Argumente auch ohne []-Syntax zugreifen: params.input zB.

Und last but not least: eine solche Klasse wie du sie beschreibst macht man in Python nicht. Wenn du Werte hast, die als Attribut vorliegen, dann schreibst du da nicht einen muehseligen getter fuer. Die eigentliche Parameter-Klasse von argparse ist gut genug, wenn du darauf bestehst, das nochmal einzupacken, schau dir mal named tuples. Oder das 3rd-party Modul attrs. Aber wie gesagt: man macht sowas eigentlich nicht.
Benutzeravatar
__blackjack__
User
Beiträge: 13103
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Also `argparse.Namespace`-Objekte noch mal in ein `namedtuple` umzupacken macht eher keinen Sinn, das ist ja genau das gleiche, nur das man die Werte nicht mehr neu zuweisen kann und `attrs` macht auch nur Sinn wenn da noch mehr dazu kommt neben den reinen Argumenten.

@Julien456935: Um Himmels willen bitte keine Vererbung verwenden um Daten in Klassen/Objekte zu bekommen. Solche Parameter übergibt man als Argument(e), nicht über Vererbung.

`parsed_params` ist im Grunde bereits genau das was Du haben möchtest: Ein reines Datenobjekt das nur die Parameter als Attribute besitzt. Das kann man als Argument im Programm herum reichen, oder nur einzelne Werte wenn es keinen Sinn macht immer das ganze Paket herum zu reichen. Der Programmteil der die Eingabedatei liest, braucht schliesslich den Namen der Ausgabedatei nicht wissen und umgekehrt. Ich würde da also nicht immer allen Programmteilen einfach alles weiterreichen, auch wenn das vielleicht erst einmal einfacher erscheint. Es macht das Programm auch etwas undurchsichtiger wenn alle möglichen Funktionen/Methoden `parsed_params` entgegen nehmen und womöglich auch noch weiter reichen, und man erst den Code selbst anschauen muss um zu erfahren was davon eigentlich konkret benutzt wird.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Sirius3
User
Beiträge: 17749
Registriert: Sonntag 21. Oktober 2012, 17:20

Meine Vorredner haben es ja schon geschrieben, eine eigene Klasse braucht man nicht, weil der Rückgabewert von Argparse.parse schon solch ein Objekt zurückliefert. Rein Syntaktisch ist der Klassenkörper nicht dafür gedacht, etwas auszuführen; also alles was vor `def __init__` steht, gehört eigentlich in __init__ hinein (außer das Import, das gehört an den Anfang der Datei).
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

Was dir noch niemand geschrieben hat: Niemand tut sich freiwillig argparse an. docopt oder click (wenn mehr etwas mehr features braucht) sind beide wesentlich einfacher zu nutzen ohne dass du dich im Vergleich zu argparse einschränken musst.
Julien456935
User
Beiträge: 19
Registriert: Donnerstag 22. November 2018, 15:26

Danke an alle! Dann werd ich diese Idee wieder verwerfen, inzwischen habe ich eine gewisse Struktur geschaffen. Das nächste mal werde ich auch die Code-Tags verwenden:)
Antworten