Ich möchte Textdateien verarbeiten, die mehrere Dokumente in unterschiedlichen Formaten enthalten. Die Dokumente werden durch drei Bindestriche getrennt, ähnlich wie in YAML.
Code: Select all
Example: Here we have some YAML code
PartOne: It is the first of three parts
---
Column1,Column2,Column3
The,second,part
is,a,CSV
---
[ "The third and last part",
"is some JSON"
]
Es gibt Python-Module zum einfachen Parsen aller Komponenten. Sie lesen normalerweise aus Dateiobjekten. Zunächst müssten die Komponenten also auseinandergenommen werden. Dies könnte erreicht werden, indem die gesamte Datei gelesen, die Komponenten aufgeteilt und dann erneut in StringIO verpackt werden, damit sie sich wie ein Dateiobjekt verhalten.
Code: Select all
import pathlib, io, yaml, csv, json
partone, parttwo, partthree = pathlib.Path("file").read_text().split("\n---\n")
print(yaml.load(io.StringIO(partone)))
print(tuple(csv.reader(io.StringIO(parttwo))))
print(json.load(io.StringIO(partthree)))
Dieser Ansatz erfordert jedoch das Lesen und Halten der gesamten Datei oder mindestens einer gesamten Komponente im Speicher. Dies ist insbesondere bei großen Bauteilen übertrieben. Deshalb suche ich nach einer Alternative, die die Datei im Streaming verarbeiten kann und dabei bei den Trennzeichen stoppt.
Optimalerweise würde ich mir einen Iterator von Dateiobjekten vorstellen, der der Reihe nach gelesen werden kann.
Code: Select all
with open("file") as file:
components = splitfile(file, "\n---\n")
print(yaml.load(next(components)))
print(tuple(csv.reader(next(components))))
print(json.load(next(components)))
Oder noch kompakter wäre ein wiederverwendbares Dateiobjekt, das jedes Trennzeichen als Zwischenende der Datei meldet.
Code: Select all
with splitfile(open("file"), "\n---\n") as file:
print(yaml.load(file))
print(tuple(csv.reader(file)))
print(json.load(file))
Ich habe darüber nachgedacht, Letzteres als Dateiobjekt-Wrapper zu implementieren. Die Handhabung aller Randfälle erwies sich jedoch als recht komplex – insbesondere, wenn ein Trennzeichen nur teilweise gelesen wird, z. B. wegen des size-Arguments für die Methoden read oder readline.
Gibt es eine Python-Bibliothek oder? Rezept, das mir helfen kann, eine solche Splitfile-Funktion zu erstellen?