Abrir un archivo con `with`
Las variables desaparecen cuando termina un programa; los archivos no. open(path, mode) da un objeto archivo, y mode indica lo que quieres: "r" para leer (por defecto), "w" para escribir y "a" para añadir. Abre siempre los archivos con un bloque with: with open(path) as file:. Al terminar el bloque, Python cierra el archivo por ti, incluso si hubo un error, así los datos no se pierden ni quedan a medio escribir. Pasa encoding="utf-8" para que el texto se lea y escriba igual en cualquier ordenador.
# 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'Leer línea a línea
file.read() devuelve todo el archivo como una sola cadena. Lo más habitual es recorrer el objeto archivo, que da una línea cada vez y sirve incluso para archivos demasiado grandes para la memoria: for line in file:. Cada línea sigue terminando en \n, así que límpiala con line.strip(). Una línea en blanco queda como la cadena vacía "" tras limpiarla, que es falsa, por lo que if text: la omite. file.readlines() y text.splitlines() dan listas de líneas cuando las quieres todas de golpe.
# 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.0Escribir y añadir
file.write(text) escribe exactamente la cadena que le das y devuelve el número de caracteres. No añade salto de línea, así que termina tú cada línea con "\n". El modo "w" primero vacía el archivo (y lo crea si no existe), de modo que abrir con "w" un archivo existente tira su contenido anterior. El modo "a" conserva lo que hay y añade al final. Solo se pueden escribir cadenas: convierte antes los números, por ejemplo con una f-string como 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())) # ''Rutas y archivos que faltan
Una ruta relativa como "fills.txt" se busca en la carpeta actual del programa; usa os.path.join(folder, name) para construir rutas sin preocuparte por los separadores. Abrir para leer un archivo que no existe lanza FileNotFoundError, que puedes capturar con try/except cuando la ausencia es un caso esperado. Para archivos pequeños, pathlib.Path(path).read_text() y .write_text(text) abren, leen o escriben y cierran en una sola llamada.
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" sobre la ruta equivocada destruye datos sin posibilidad de deshacer. Decide un formato simple (un registro por línea, campos separados por comas) y escribe juntos el lector y el escritor para que estén de acuerdo. Pronto conocerás el formato CSV, que formaliza justo esta idea.with open(path, mode, encoding="utf-8") as file:abre el archivo y siempre lo cierra.for line in file:lee una línea cada vez;line.strip()quita el salto de línea."w"vacía el archivo,"a"añade;writeno añade salto de línea.
A continuación: archivos CSV, la forma estándar de guardar tablas de precios y operaciones.
Lab: qué se califica
- Cargar una lista de seguimiento desde un archivo con
read_symbols25 pts - Convertir un archivo de ejecuciones en tuplas con
parse_trades25 pts - Guardar un informe de ganancias y pérdidas con
write_report25 pts - Añadir a un registro sin perderlo con
append_lines25 pts