Arquivos e E/S
Ler e escrever arquivos é uma tarefa diária - logs, configurações, uploads e exportações. pathlib.Path fornece uma API de caminho orientada a objetos, enquanto os gerenciadores de contexto garantem que os descritores sejam fechados mesmo quando ocorrem erros.
Receita
from pathlib import Path
path = Path("data/config.json")
path.parent.mkdir(parents=True, exist_ok=True)
path.write_text('{"debug": true}', encoding="utf-8")
raw = path.read_bytes()
text = raw.decode("utf-8")Quando usar isso:
- Carregar configuração JSON/YAML/TOML na inicialização
- Escrever logs de auditoria e exportações CSV
- Transmitir arquivos grandes sem carregar todos os bytes
- Atualizações atômicas de configuração via arquivo temporário + renomear
Exemplo de Trabalho
import json
import tempfile
from pathlib import Path
def atomic_write_json(path: Path, payload: dict) -> None:
path.parent.mkdir(parents=True, exist_ok=True)
with tempfile.NamedTemporaryFile(
mode="w",
encoding="utf-8",
dir=path.parent,
delete=False,
suffix=".tmp",
) as tmp:
json.dump(payload, tmp, indent=2)
tmp_path = Path(tmp.name)
tmp_path.replace(path)
def tail_lines(path: Path, max_lines: int = 50) -> list[str]:
if not path.exists():
return []
lines = path.read_text(encoding="utf-8").splitlines()
return lines[-max_lines:]
def copy_binary(src: Path, dst: Path, chunk_size: int = 1024 * 64) -> None:
dst.parent.mkdir(parents=True, exist_ok=True)
with src.open("rb") as rf, dst.open("wb") as wf:
while chunk := rf.read(chunk_size):
wf.write(chunk)
if __name__ == "__main__":
cfg = Path("data/settings.json")
atomic_write_json(cfg, {"retries": 3, "timeout": 30})
print(tail_lines(Path("data/app.log")))O que isso demonstra:
- Escrita atômica via arquivo temporário no diretório de destino e depois
Path.replace - Leituras de texto sempre passam
encoding="utf-8" - Cópia binária transmite blocos - memória limitada para arquivos grandes
mkdir(parents=True, exist_ok=True)cria diretórios aninhados com segurança
Mergulho Profundo
Como Funciona
- Texto vs binário -
"r"/"w"retornamstr;"rb"/"wb"retornambytes. - Gerenciadores de contexto -
with open(...) as fchamaf.close()emfinally. - pathlib - Envolve
os/opencom métodosPath(read_text,glob,iterdir). - Codificações - UTF-8 padrão para texto multiplataforma; especifique a política de erros (
strict,replace). - Descritores de arquivo - Limites do SO para arquivos abertos; sempre feche ou use
with.
Operações Comuns de Caminho
| Tarefa | pathlib |
|---|---|
| Juntar caminhos | base / "child" / "file.txt" |
| Verificação de existência | path.exists() |
| Glob | path.glob("**/*.py") |
| Resolver | Caminho absoluto path.resolve() |
Notas do Python
from contextlib import ExitStack
with ExitStack() as stack:
a = stack.enter_context(path_a.open())
b = stack.enter_context(path_b.open())
# ambos fecham ao sairArmadilhas
- Codificação ausente - O padrão da plataforma pode não ser UTF-8 no Windows. Correção:
encoding="utf-8"sempre para texto. - Leitura de arquivos enormes com read_text - Carrega o arquivo inteiro na RAM. Correção: Itere sobre linhas ou leia blocos binários.
- Concatenação de strings de caminho -
"dir" + "/file"quebra no Windows. Correção:Path("dir") / "file". - Corridas Toctou - Verifique
exists()e depois abra - outro processo pode excluir. Correção:try/except FileNotFoundError. - Esquecer nova linha ao escrever - Logs se juntam. Correção: Escreva
line + "\n"ouprint(..., file=fh).
Alternativas
| Alternativa | Usar Quando | Não Usar Quando |
|---|---|---|
pathlib | A maioria das tarefas de arquivo | Precisa de flags os.open de nível mais baixo |
aiofiles | Uploads assíncronos FastAPI | Script CLI síncrono |
tempfile | Escritas atômicas, rascunho | Caminhos de armazenamento permanentes |
| Armazenamento de objetos (S3) | Ativos compartilhados duráveis | Apenas configuração de desenvolvimento local |
FAQs
pathlib ou os.path?
Prefira pathlib para código novo - operadores legíveis e auxiliares de leitura/escrita de alto nível.
Como faço para anexar a um arquivo de log?
with path.open("a", encoding="utf-8") as fh: fh.write(line + "\n")
Qual modo para imagens binárias?
"rb" e "wb" - nunca decodifique imagens como texto UTF-8.
Como listar arquivos recursivamente?
for p in Path("src").rglob("*.py"): print(p)
O que é substituição atômica?
Escreva temporariamente no mesmo diretório do sistema de arquivos, depois Path.replace - leitores veem o arquivo antigo ou novo, nunca parcial.
Como lidar com arquivos ausentes?
Capture FileNotFoundError ou verifique path.exists() quando a configuração opcional for aceitável.
pathlib pode ler JSON diretamente?
Não - leia o texto e depois json.loads. Ou use json.load com um manipulador de arquivo aberto.
Qual política de erro de codificação devo usar?
strict para pipelines validados; replace ou backslashreplace apenas para ingestão de log com perdas.
Como obter o tamanho do arquivo?
path.stat().st_size sem ler o conteúdo.
O `with` fecha em caso de exceção?
Sim - o protocolo do gerenciador de contexto executa __exit__ e fecha o arquivo mesmo quando um erro é propagado.
Relacionados
- Strings e f-strings - codificar/decodificar texto
- Gerenciadores de Contexto - padrões avançados de
with - Arrays, bytes e memoryview - buffers binários
- Guia Rápido de Ambientes Virtuais - caminhos de projeto
Versões da Stack: Esta página foi escrita para Python 3.14.0 (estável 3.14, manutenção 3.13), FastAPI 0.115+, Django 5.2, Flask 3.1, Pydantic 2, PyTorch 2.6+, pandas 2.2+, Polars 1.x, ruff 0.9+, e uv 0.6+.