Abrir um arquivo com `with`
As variáveis desaparecem quando o programa termina; os arquivos não. open(path, mode) dá um objeto de arquivo, e mode diz o que você quer: "r" para ler (o padrão), "w" para escrever e "a" para acrescentar. Abra sempre os arquivos com um bloco with: with open(path) as file:. Ao fim do bloco, o Python fecha o arquivo por você, mesmo que haja um erro, para que os dados não se percam nem fiquem pela metade. Passe encoding="utf-8" para que o texto seja lido e escrito igual em qualquer computador.
# 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'Ler linha por linha
file.read() devolve o arquivo inteiro como uma só string. O mais comum é percorrer o objeto de arquivo, que dá uma linha por vez e funciona até para arquivos grandes demais para a memória: for line in file:. Cada linha ainda termina em \n, então limpe-a com line.strip(). Uma linha em branco vira a string vazia "" depois de limpa, que é falsa, portanto if text: a ignora. file.readlines() e text.splitlines() dão listas de linhas quando você as quer todas de uma vez.
# 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.0Escrever e acrescentar
file.write(text) escreve exatamente a string que você der e devolve o número de caracteres. Ela não acrescenta quebra de linha, então termine cada linha com "\n" você mesmo. O modo "w" primeiro esvazia o arquivo (e o cria se não existir), portanto abrir um arquivo existente com "w" descarta o conteúdo antigo. O modo "a" mantém o que há e acrescenta no fim. Só se podem escrever strings: converta antes os números, por exemplo com uma 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())) # ''Caminhos e arquivos ausentes
Um caminho relativo como "fills.txt" é procurado na pasta atual do programa; use os.path.join(folder, name) para montar caminhos sem se preocupar com separadores. Abrir para leitura um arquivo que não existe gera FileNotFoundError, que você pode capturar com try/except quando a ausência é um caso esperado. Para arquivos pequenos, pathlib.Path(path).read_text() e .write_text(text) abrem, leem ou escrevem e fecham em uma só chamada.
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" no caminho errado destrói dados sem desfazer. Decida um formato simples (um registro por linha, campos separados por vírgulas) e escreva o leitor e o escritor juntos para que combinem. Você logo conhecerá o formato CSV, que formaliza exatamente essa ideia.with open(path, mode, encoding="utf-8") as file:abre o arquivo e sempre o fecha.for line in file:lê uma linha por vez;line.strip()remove a quebra de linha."w"esvazia o arquivo,"a"acrescenta;writenão acrescenta quebra de linha.
A seguir: arquivos CSV, a forma padrão de guardar tabelas de preços e operações.
Lab: o que é avaliado
- Carregar uma lista de acompanhamento de um arquivo com
read_symbols25 pts - Transformar um arquivo de execuções em tuplas com
parse_trades25 pts - Salvar um relatório de lucros e perdas com
write_report25 pts - Acrescentar a um log sem perdê-lo com
append_lines25 pts