Einlesen von sehr langen Textdateien in einen Buffer

Du hast eine Idee für ein Projekt?
Antworten
ihPyP
User
Beiträge: 58
Registriert: Samstag 4. September 2010, 23:06

Hallo,

ich habe ein Problem und hoffe, dass man mir hier weiterhelfen kann. Ich möchte gerne eine Textdatei in einen Buffer einlesen, um diesen zu durchsuchen und einzelne Ausdrücke zu ersetzen.
Das Einlesen mache ich bisher mit der folgenden Routine.

Code: Alles auswählen

def Read_to_List(Path, correct=0):
    lines = list()
    inputfile = open(Path,'r')
    #
    for line in inputfile:
        if correct == 1:
            p = line.find("#")
            if p > 0: line = line[:p].strip()
            if line != "" : lines.append(line)
        else:
            lines.append(line)
    #
    inputfile.close()
    #
    return lines
Ich habe gerade gesehen, dass die Datei, welche ich mit der Variable "Path" an die Routine Read_to_List übergebe, Zeilen beinhaltet, die mehr als 560 Zeichen beinhaltet. Ich habe den Eindruck, dass diese Zeilen nicht vollständig eingelesen werden. Könnt ihr bestätigen, dass derartig lange Zeilen auf diese Weise nicht vollständig/korrekt eingelesen werden. Wie kann ich das Problem umgehen.

Wie gesagt mein Ziel ist:
Eine Textdatei durchsuchen und einzelne Ausdrücke $Variable1$ durch XXXX ersetzen.

Vielen Dank im Voraus für die Hilfe.-
Zuletzt geändert von Anonymous am Montag 22. August 2011, 14:07, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Code-Tags gesetzt.
BlackJack

@ihPyP: Mehr als 560 Zeichen sind kein Problem. Die Grössenbegrenzung von Zeichenketten ist der verfügbare Speicher den der Prozess auf Deinem System anfordern und adressieren kann.

Das `correct`-Argument würde ich weglassen und die Funktion grundsätzlich die Kommentarzeilen ignorieren lassen. Zeilen ohne weitere Änderungen in eine Liste einlesen geht schon mit `list()` auf einem Dateiobjekt, da braucht man keine extra Funktion für.

Du entfernst bei Zeilen mit Kommentar auch den Zeilenumbruch, bei denen ohne Kommentar aber nicht. Ist das gewollt?

Falls Du das `correct`-Argument behalten möchtest, solltest Du es in `strip_comments` oder `ignore_comments` oder ähnlich umbenennen und bitte einen `bool`-Wert verwenden statt 0 und 1.
ihPyP
User
Beiträge: 58
Registriert: Samstag 4. September 2010, 23:06

Hi BlackJack,

also die Funktion Kommentare entfernen ist für meinen Fall schon sehr sinnvoll und sollte daher erhalten bleiben. Aber Deine weiteren Kommentare fand ich interessant.

Könntest Du mir bitte einmal posten, wie Du den Zeilenumbruch wieder anfügen würdest.
BlackJack

@ihPyP: Ich meinte nicht das Du die Funktionalität für das Entfernen von Kommentaren rauswerfen solltest, sondern das Argument und damit die Wahlmöglichkeit ob das passieren soll oder nicht. Denn einlesen *ohne* Entfernen der Kommentare geht ganz einfach, da braucht man keine eigene Funktion für. Beziehungsweise sollte man zumindest die Entscheidung nicht bei jeder Zeile machen wenn sich die Bedingung während aller Zeilen nicht ändert.

Wieder anfügen eines Zeilenumbruchs: Vor dem entfernen eines Kommentars testen ob die Zeile mit einem Zeilenende-Zeichen endet, und so eines gegebenfalls halt nach dem entfernen eines Kommentars wieder anfügen. Das sollten AFAIK alles Operationen sein, die im Tutorial in der Python-Dokumentation vorkommen.
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

ihPyP hat geschrieben:also die Funktion Kommentare entfernen ist für meinen Fall schon sehr sinnvoll und sollte daher erhalten bleiben. Aber Deine weiteren Kommentare fand ich interessant.

Könntest Du mir bitte einmal posten, wie Du den Zeilenumbruch wieder anfügen würdest.
Ich mag ja reguläre Ausdrücke und würde das damit umsetzen. Das Abschneiden des Kommentars sollte man meiner Meinung nach allerdings nicht mit dem Einlesen mischen.

Code: Alles auswählen

import re
def read_data(path, strip_comments=False):
    with open(path, 'r') as f:
        data = f.readlines()

    if strip_comments:
        stripper = re.compile(r'^(.*?)(#.*)?$')
        data = [stripper.sub('\\1', line) for line in data]
    return data
Die Routine ist natürlich noch genau so "dumm" wie vorher. Ein # in einem String würde als Kommentarbeginn erfasst.
BlackJack

@/me: Du mischst das Einlesen und das Kommentar-entfernen hier immer noch — es ist in einer Funktion. So ist es jetzt auch etwas speicherhungriger, denn beide Listen müssen gleichzeitig exisitieren. Und Du filterst reine Kommentarzeilen nicht mehr komplett raus.
Antworten