Eine Datei mit `with` öffnen
Variablen verschwinden, wenn ein Programm endet; Dateien nicht. open(path, mode) liefert ein Dateiobjekt, und mode sagt, was Sie wollen: "r" zum Lesen (Standard), "w" zum Schreiben und "a" zum Anhängen. Öffnen Sie Dateien immer mit einem with-Block: with open(path) as file:. Am Ende des Blocks schließt Python die Datei für Sie, auch wenn darin ein Fehler auftrat, sodass Daten weder verloren gehen noch halb geschrieben bleiben. Geben Sie encoding="utf-8" an, damit Text auf jedem Rechner gleich gelesen und geschrieben wird.
# Write a file, then read it back
with open("fills.txt", "w", encoding="utf-8") as file:
file.write("AAPL,184.25,200\n")
file.write("MSFT,410.20,50\n")
with open("fills.txt", encoding="utf-8") as file:
text = file.read()
print(repr(text)) # 'AAPL,184.25,200\nMSFT,410.20,50\n'Zeile für Zeile lesen
file.read() liefert die ganze Datei als einen String. Häufiger durchläuft man das Dateiobjekt selbst, das eine Zeile nach der anderen liefert und auch bei Dateien funktioniert, die nicht in den Speicher passen: for line in file:. Jede Zeile endet noch mit \n, also bereinigen Sie sie mit line.strip(). Eine Leerzeile wird nach dem Bereinigen zum leeren String "", der als falsch gilt, daher überspringt if text: sie. file.readlines() und text.splitlines() liefern Listen von Zeilen, wenn Sie alle auf einmal wollen.
# Read line by line, skipping blank lines
with open("fills.txt", "a", encoding="utf-8") as file:
file.write("\n") # a blank line
total = 0.0
with open("fills.txt", encoding="utf-8") as file:
for line in file:
text = line.strip()
if not text:
continue
symbol, price, quantity = text.split(",")
total += float(price) * int(quantity)
print(round(total, 2)) # 57360.0Schreiben und Anhängen
file.write(text) schreibt genau den übergebenen String und liefert die Zahl der Zeichen. Es fügt keinen Zeilenumbruch hinzu, beenden Sie also jede Zeile selbst mit "\n". Der Modus "w" leert die Datei zuerst (und legt sie an, falls sie nicht existiert); eine vorhandene Datei mit "w" zu öffnen wirft ihren alten Inhalt weg. Der Modus "a" behält das Vorhandene und hängt hinten an. Es lassen sich nur Strings schreiben: Wandeln Sie Zahlen zuerst um, etwa mit einem f-String wie f"{price:.2f}".
# "w" starts over, "a" adds to the end
with open("log.txt", "w", encoding="utf-8") as file:
file.write("start\n")
with open("log.txt", "a", encoding="utf-8") as file:
file.write("order 1 filled\n")
file.write(f"pnl {12.5:+.2f}\n")
with open("log.txt", encoding="utf-8") as file:
print(file.read().splitlines()) # ['start', 'order 1 filled', 'pnl +12.50']
with open("log.txt", "w", encoding="utf-8") as file:
pass # opening with "w" emptied it
with open("log.txt", encoding="utf-8") as file:
print(repr(file.read())) # ''Pfade und fehlende Dateien
Ein relativer Pfad wie "fills.txt" wird im aktuellen Ordner des Programms gesucht; mit os.path.join(folder, name) bauen Sie Pfade, ohne sich um Trennzeichen zu kümmern. Das Öffnen einer nicht vorhandenen Datei zum Lesen löst FileNotFoundError aus, das Sie mit try/except abfangen können, wenn das Fehlen ein erwarteter Fall ist. Für kleine Dateien erledigen pathlib.Path(path).read_text() und .write_text(text) Öffnen, Lesen oder Schreiben und Schließen in einem Aufruf.
import os
from pathlib import Path
# A missing file is an exception you can handle
def count_lines(path):
try:
with open(path, encoding="utf-8") as file:
return len(file.read().splitlines())
except FileNotFoundError:
return 0
print(count_lines("fills.txt")) # 3
print(count_lines("nope.txt")) # 0
# pathlib does open + read + close in one call
path = Path(os.path.join(".", "fills.txt"))
print(path.read_text(encoding="utf-8").splitlines()[0]) # AAPL,184.25,200"w" auf dem falschen Pfad zerstört Daten ohne Rückgängig. Legen Sie ein einfaches Format fest (ein Datensatz pro Zeile, durch Kommas getrennte Felder) und schreiben Sie Leser und Schreiber zusammen, damit sie sich einig sind. Als Nächstes lernen Sie das CSV-Format kennen, das genau diese Idee formalisiert.with open(path, mode, encoding="utf-8") as file:öffnet die Datei und schließt sie immer.for line in file:liest eine Zeile nach der anderen;line.strip()entfernt den Zeilenumbruch."w"leert die Datei,"a"hängt an;writefügt keinen Zeilenumbruch hinzu.
Als Nächstes: CSV-Dateien, der Standardweg, Tabellen mit Preisen und Trades zu speichern.
Lab: Was bewertet wird
- Mit
read_symbolseine Watchlist aus einer Datei laden25 Pkt. - Mit
parse_tradeseine Datei mit Fills in Tupel umwandeln25 Pkt. - Mit
write_reporteinen Gewinn-und-Verlust-Bericht speichern25 Pkt. - Mit
append_linesein Protokoll ergänzen, ohne es zu verlieren25 Pkt.