@Frokuss: ich weiß ja nicht, wie Du Python lernst, aber Deine Interpretation der Sprache ist lustig. Es gibt kein _protected_ oder __privat__, per Konvention bedeutet _intern "nicht für die allgemeine Verwendung gedacht", und mehr braucht man auch nicht.
`__DirWithFile__` ist komplett überflüssig und in allgemeinen auch falsch. Das letzte Zeichen, oder das letzte Element einer Liste bekommt man mit negativen Indizes, pathname[-1], da muß man nicht extra die Länge bestimmen. Zum Arbeiten mit Pfaden gibt es pathlib und dort werden Pfade einfach per / zusammengesetzt:
Code: Alles auswählen
path = pathlib.Path('/irgend/ein/pfad/')
full_filename = path / filename
Dafür eine Methode zu definieren ist also nicht nur umständlich und fehleranfällig, sondern erschwert jedem Leser, was da wirklich passiert, weil er sich in Deine Logik einlesen muß, statt das Wissen der Standardbibliotheken nutzen zu können. Die Methode ist außerdem gar keine Methode und gehört nicht in die Klasse, das erkennt man daran, dass `self` gar nicht benutzt wird.
Es ist auch seltsam, dass man Pfad und Filename separat setzen kann. Da anscheinend sowieso nur eine Datei referenziert wird, ist so eine Trennung überflüssig und macht das Programm nur unnötig lang und schwer zu verstehen, weil jeder erwartet, Dateinamen inklusive Pfad angeben zu können.
Es ist nicht so einfach, aus csv-Dateien den Separator erraten zu können. Sicherer ist es, diesen explizit beim Laden anzugeben. Wenn Du es aber doch raten mußt, dann sind reguläre Ausdrücke zum Suchen eines einzelnen Zeichens unnötig kompliziert.
Die Prüfung "sep=" sieht sehr abenteuerlich aus. Wenn kein eindeutiger Separator gefunden wird, ist es dann sinnvoll None als Ergebnis zu liefern? Wie wird das weiterverarbeitet? Oft ist es ja so, dass None bedeutet, irgendeinen Defaultwert zu verwenden.
Da sollte irgendwo ein Hinweis sein, dass GetSep die erste Zeile erwartet. Statt überall ein `printy`-Argument anzugeben, benutzt man das logging-Modul.
Auf None prüft man üblicherweise mit `is`, das gilt aber nicht bei anderen Werten.
In `GetMetas`: das Zeile-Ende-Zeichen löscht man, bevor man die Zeile splittet. Dateien werden mit dem with-Statement geöffnet, das impliziert ein close().
Keine kryptischen Variablennamen verwenden, v1 und v2, gehts noch? Das eine ist ein Separater, das andere sind Spaltenüberschriften. Üblicherweise liest man auch gleich die ganze Datei, denn so mußt Du beim Lesen der eigentlichen Daten ja wieder prüfen, ob die erste Zeile ein sep= enthält.
`Hilfe` braucht man nicht, weil mit der `help`-Funktion von Python automatisch die Klassenstruktur in einen Hilfetext verwandelt wird.
Alle Klassenattribute sind keine.
Was bleibt ist das:
Code: Alles auswählen
import logging
logger = logging.getLogger(__name__)
def guess_seperator(line):
#Optional in der ersten Zeile einer CSV! (z.B. sep=,) https://de.wikipedia.org/wiki/CSV_(Dateiformat)#Besonderheiten_beim_Import
if line.startswith("sep="):
sep = line.strip()[-1]
explicit = True
logger.info("CSV-Vorgegebener Seperator ist: %s", sep)
else:
explicit = False
seps = set(c for c in [",", ";", "\t"] if c in line)
if len(seps) == 1:
sep = seps.pop()
else:
logging.info("konnte keinen eindeutigen Seperator finden:\n%s", line)
sep = None
return sep, explicit
class DatenEinlesen:
# TODO: besseren Klassennamen finden
def __init__(self, filename, sep=None):
"""
Arguments:
filename: csv-filename, optionally including path
sep: separator character, if None try to guess
"""
self.filename = filename
self.read_header()
print("Metadaten generiert...")
print(f"Separator: {self.seperator}")
print(f"Merkmale: {self.merkmale}")
def read_header(self):
with open(self.filename) as lines:
header = next(lines)
sep, explicit = guess_seperator(header)
if explicit:
# first line was sep=
header = next(lines)
self.seperator = sep
if sep is not None:
self.merkmale = header.strip().split(sep)
else:
# TODO: hier sollte etwas sinnvolles passieren
self.merkmale = None
[/python]