Introdução parte 3
Gerenciamento de Arquivo
O gerenciamento de arquivos em Python permite que você abra, leia, escreva, crie, edite e exclua arquivos de forma simples e direta, usando a função open() e métodos associados. Ele serve para lidar com arquivos de texto, binários, logs, configurações, entre outros.
Abrindo um arquivo
A função básica é:
open(caminho, modo)
Os modos mais comuns são:
'r'– leitura (read)'w'– escrita (write, sobrescreve)'a'– anexar (append, adiciona no fim)'x'– criar (erro se já existir)'b'– modo binário (usar junto:'rb','wb')'+'– leitura e escrita ('r+','w+')
Leitura
Para ler um arquivo, podemos fazer:
with open("arquivo.txt", "r") as f:
conteudo = f.read()
print(conteudo)
Você também pode ler linha por linha:
with open("arquivo.txt") as f:
for linha in f:
print(linha.strip())
Escrita
Para escrever em um arquivo, podemos fazer:
with open("arquivo.txt", "w") as f:
f.write("Primeira linha\n")
f.write("Segunda linha\n")
O modo 'w' apaga o conteúdo anterior. Se quiser manter o que já tem, use 'a':
with open("arquivo.txt", "a") as f:
f.write("Nova linha ao final\n")
Escrever várias linhas
Para escrever várias linhas em um arquivo, podemos fazer:
linhas = ["linha1\n", "linha2\n", "linha3\n"]
with open("arquivo.txt", "w") as f:
f.writelines(linhas)
Modo seguro: with
O with é o jeito mais seguro de lidar com arquivos. Ele faz,
- Abre o arquivo
- Fecha automaticamente (mesmo com erro)
- Libera o recurso corretamente
Sem with, você teria que fechar manualmente:
f = open("arquivo.txt", "r")
dados = f.read()
f.close()
Se você esquecer o close(), o arquivo pode ficar bloqueado.
Leitura e escrita juntas
with open("arquivo.txt", "r+") as f:
conteudo = f.read()
f.seek(0)
f.write("Novo conteúdo\n")
O seek(0) reposiciona o cursor no início do arquivo.
Arquivos binários
Para ler ou escrever arquivos binários (imagens, áudio, etc.):
with open("foto.jpg", "rb") as f:
dados = f.read()
with open("saida.jpg", "wb") as f:
f.write(dados)
Trabalhar com caminhos
Use o módulo os ou pathlib para criar caminhos seguros:
from pathlib import Path
arquivo = Path("dados") / "registro.txt"
with open(arquivo, "r") as f:
print(f.read())
Verificar se arquivo existe
import os
if os.path.exists("arquivo.txt"):
print("Arquivo existe")
Ou com Path:
from pathlib import Path
if Path("arquivo.txt").is_file():
print("Existe")
Remover arquivos
import os
os.remove("arquivo.txt")
Ou:
from pathlib import Path
Path("arquivo.txt").unlink()
Path
O Path é uma classe do módulo pathlib usada para trabalhar com caminhos de arquivos e diretórios em Python. Com ele, podemos montar caminhos, verificar se arquivos existem, criar diretórios, ler arquivos, escrever arquivos e navegar pela estrutura do sistema de arquivos de uma forma mais simples e organizada.
Para usar o Path, primeiro precisamos importar ele do módulo pathlib.
from pathlib import Path
Vamos ver como criar caminho simples. A variável caminho não representa o conteúdo do arquivo e sim o caminho até o arquivo.
from pathlib import Path
caminho = Path('/tmp/arquivo.txt')
print(caminho)
# Resultado: /tmp/arquivo.txt
O arquivo não precisa existir para que o objeto Path seja criado.
Criando um caminho relativo
Nesse caso, o caminho é relativo ao diretório atual onde o script está sendo executado.
from pathlib import Path
caminho = Path('arquivo.txt')
print(caminho)
# Resultado: arquivo.txt
Criando caminhos com partes separadas
O operador / pode ser usado para juntar partes de um caminho. Isso deixa o código mais limpo do que montar caminhos usando concatenação de strings.
from pathlib import Path
caminho = Path('/tmp') / 'logs' / 'app.log'
print(caminho)
# Resultado: /tmp/logs/app.log
Método exists()
É usado para verificar se um caminho existe.
from pathlib import Path
caminho = Path('/tmp/arquivo.txt')
if caminho.exists():
print('O caminho existe!')
else:
print('O caminho não existe!')
Esse método retorna True se o arquivo ou diretório existir, e False caso não exista.
Método is_file()
É usado para verificar se o caminho é um arquivo.
from pathlib import Path
caminho = Path('/tmp/arquivo.txt')
if caminho.is_file():
print('É um arquivo!')
else:
print('Não é um arquivo!')
Método is_dir()
É usado para verificar se o caminho é um diretório.
from pathlib import Path
caminho = Path('/tmp')
if caminho.is_dir():
print('É um diretório!')
else:
print('Não é um diretório!')
Método mkdir()
Usado para criar um diretório.
from pathlib import Path
diretorio = Path('/tmp/teste')
diretorio.mkdir()
print('Diretório criado!')
Se o diretório já existir, o Python vai gerar erro. Para evitar esse erro, podemos usar exist_ok=True.
from pathlib import Path
diretorio = Path('/tmp/teste')
diretorio.mkdir(exist_ok=True)
print('Diretório criado ou já existente!')
Também podemos criar diretórios intermediários usando parents=True. Isso é útil para criar vários diretório de uma única vez.
from pathlib import Path
diretorio = Path('/tmp/teste/logs/app')
diretorio.mkdir(parents=True, exist_ok=True)
print('Diretórios criados!')
Método touch()
Usado para criar um arquivo vazio.
from pathlib import Path
arquivo = Path('/tmp/arquivo.txt')
arquivo.touch()
print('Arquivo criado!')
Se o arquivo já existir, nada acontece.
Método write_text()
Usado para escrever texto dentro de um arquivo.
from pathlib import Path
arquivo = Path('/tmp/arquivo.txt')
arquivo.write_text('Olá mundo!\n', encoding='utf-8')
Esse método cria o arquivo caso ele não exista. Se o arquivo já existir, o conteúdo antigo será substituído.
Método read_text()
Usado para ler o conteúdo de um arquivo como texto.
from pathlib import Path
arquivo = Path('/tmp/arquivo.txt')
conteudo = arquivo.read_text(encoding='utf-8')
print(conteudo)
# Resultado: Olá mundo!
Método open()
Usado para abrir um arquivo. Ele funciona parecido com o open() tradicional do Python, mas é chamado diretamente a partir do objeto Path.
from pathlib import Path
arquivo = Path('/tmp/arquivo.txt')
with arquivo.open('r', encoding='utf-8') as file:
conteudo = file.read()
print(conteudo)
Também podemos usar para escrever no arquivo.
from pathlib import Path
arquivo = Path('/tmp/arquivo.txt')
with arquivo.open('w', encoding='utf-8') as file:
file.write('Novo conteúdo\n')
Método unlink()
Usado para remover um arquivo ou um link simbólico.
from pathlib import Path
arquivo = Path('/tmp/arquivo.txt')
arquivo.unlink()
print('Arquivo removido!')
Se o arquivo não existir, o Python vai gerar erro. Para evitar isso, podemos verificar antes.
from pathlib import Path
arquivo = Path('/tmp/arquivo.txt')
if arquivo.exists():
arquivo.unlink()
print('Arquivo removido!')
else:
print('Arquivo não existe!')
Método rename()
Usado para renomear ou mover um arquivo.
from pathlib import Path
arquivo = Path('/tmp/arquivo.txt')
novo_nome = Path('/tmp/novo-arquivo.txt')
arquivo.rename(novo_nome)
print('Arquivo renomeado!')
Método glob()
Usado para procurar arquivos dentro de um diretório seguindo um padrão.
from pathlib import Path
diretorio = Path('/tmp')
for arquivo in diretorio.glob('*.txt'):
print(arquivo)
Nesse exemplo, o Python vai listar todos os arquivos terminados com .txt dentro de /tmp. Podemos ordenar também:
from pathlib import Path
diretorio = Path('/tmp')
for arquivo in sorted(diretorio.glob('*.txt')):
print(arquivo)
Método rglob()
Usado para procurar arquivos de forma recursiva.
from pathlib import Path
diretorio = Path('/tmp')
for arquivo in diretorio.rglob('*.log'):
print(arquivo)
A diferença é que o rglob() procura também dentro dos subdiretórios.
Método iterdir()
Usado para listar o conteúdo de um diretório.
from pathlib import Path
diretorio = Path('/tmp')
for item in diretorio.iterdir():
print(item)
Esse método retorna arquivos e diretórios que estão dentro do caminho informado.
Método absolute()
Usado para retornar o caminho absoluto.
from pathlib import Path
caminho = Path('arquivo.txt')
print(caminho.absolute())
# Resultado: /tmp/arquivo.txt
Se o arquivo estiver no diretório atual, o Python vai mostrar o caminho completo até ele.
Método resolve()
Usado para resolver o caminho completo de forma mais precisa.
from pathlib import Path
caminho = Path('arquivo.txt')
print(caminho.resolve())
# Resultado: /tmp/arquivo.txt
Esse método também pode resolver links simbólicos.
O método absolute() é usado para retornar o caminho absoluto, sem resolver links simbólicos e sem normalizar completamente o caminho.
Já o método resolve() é usado para retornar o caminho absoluto resolvido. Ele normaliza o caminho e também pode resolver links simbólicos.
Atributo name
Retorna o nome final do caminho.
from pathlib import Path
caminho = Path('/tmp/arquivo.txt')
print(caminho.name)
# Resultado: arquivo.txt
Atributo stem
Retorna o nome do arquivo sem a extensão.
from pathlib import Path
caminho = Path('/tmp/arquivo.txt')
print(caminho.stem)
# Resultado: arquivo
Atributo suffix
Retorna a extensão do arquivo.
from pathlib import Path
caminho = Path('/tmp/arquivo.txt')
print(caminho.suffix)
# Resultado: .txt
Atributo parent
Retorna o diretório pai do caminho.
from pathlib import Path
caminho = Path('/tmp/logs/app.log')
print(caminho.parent)
# Resultado: /tmp/logs
DocStrings
As docstrings (document strings) são strings de documentação usadas para explicar o propósito de um módulo, classe, função ou método em Python. Elas são escritas logo após a definição de algo (usando aspas triplas """) e servem para documentar o código de forma clara e acessível, tanto para humanos quanto para ferramentas automáticas, como o help() e geradores de documentação.
def somar(a, b):
"""Soma dois números e retorna o resultado."""
return a + b
Agora, se você fizer:
help(somar)
A saída será:
Help on function somar in module __main__:
somar(a, b)
Soma dois números e retorna o resultado.
class Conta:
"""Representa uma conta bancária com saldo."""
def __init__(self, saldo):
"""Inicializa a conta com o saldo informado."""
self.saldo = saldo
def depositar(self, valor):
"""Adiciona um valor ao saldo."""
self.saldo += valor
Docstring com descrição dos parâmetros
def dividir(a, b):
"""
Divide a por b.
Parâmetros:
a (float): O numerador.
b (float): O denominador (não pode ser zero).
Retorna:
float: O resultado da divisão.
Levanta:
ValueError: Se b for zero.
"""
if b == 0:
raise ValueError("O denominador não pode ser zero.")
return a / b
Enum
O enum.Enum é uma forma de criar conjuntos de constantes nomeadas. Ele faz parte do módulo enum, incluído na biblioteca padrão desde o Python 3.4. Usar enum.Enum é útil quando você tem valores fixos e limitados que fazem sentido ter nomes simbólicos, como dias da semana, estados de um sistema, tipos de erro, etc. Ao invés de usar strings ou números soltos, você organiza essas opções em uma estrutura clara, segura e legível.
from enum import Enum
class Cor(Enum):
VERMELHO = 1
VERDE = 2
AZUL = 3
Agora você pode usar essas cores assim:
print(Cor.VERMELHO) # Cor.VERMELHO
print(Cor.VERMELHO.name) # VERMELHO
print(Cor.VERMELHO.value) # 1
Você pode iterar sobre os membros do Enum:
for cor in Cor:
print(cor.name, cor.value)
E também pode acessar assim:
Cor['VERMELHO'] # retorna Cor.VERMELHO
Cor(1) # retorna Cor.VERMELHO
Se você tentar acessar um valor que não existe, dá erro:
Cor(4) # ValueError
Um enum não é igual à string ou ao número diretamente:
Cor.VERMELHO == "VERMELHO" # False
Cor.VERMELHO == 1 # False
Só funciona assim:
Cor.VERMELHO.name == "VERMELHO" # True
Cor.VERMELHO.value == 1 # True
Datetime
O módulo datetime serve para trabalhar com datas e horários, de forma precisa, estruturada e segura. Ele é parte da biblioteca padrão e fornece classes para representar:
- Data (
date) - Hora (
time) - Data e hora combinadas (
datetime) - Diferença entre datas (
timedelta) - Informações sobre fuso horário (
timezone)
É uma ferramenta essencial para qualquer sistema que lide com datas, agendamentos, logs, relatórios ou controle de tempo.
Classe datetime
A mais usada é datetime.datetime, que representa data + hora:
from datetime import datetime
agora = datetime.now()
print(agora) # Exemplo: 2025-06-21 14:36:00.123456
Você pode acessar partes específicas:
print(agora.year) # Ano
print(agora.month) # Mês
print(agora.day) # Dia
print(agora.hour) # Hora
print(agora.minute) # Minuto
print(agora.second) # Segundo
Criar uma data/hora específica
dt = datetime(2024, 12, 25, 10, 30)
print(dt) # 2024-12-25 10:30:00
Formatando datas
print(agora.strftime('%d/%m/%Y')) # 21/06/2025
print(agora.strftime('%H:%M:%S')) # 14:36:00
print(agora.strftime('%d de %B de %Y')) # 21 de June de 2025
Convertendo string para data
texto = '21/06/2025 14:30'
dt = datetime.strptime(texto, '%d/%m/%Y %H:%M')
print(dt) # 2025-06-21 14:30:00
Diferença entre datas: timedelta
from datetime import timedelta
agora = datetime.now()
amanha = agora + timedelta(days=1)
ontem = agora - timedelta(days=1)
print(amanha)
print(ontem)
Você pode usar timedelta para somar/subtrair dias, horas, minutos, etc.
Comparando datas
data1 = datetime(2025, 6, 21)
data2 = datetime(2025, 6, 22)
if data2 > data1:
print("data2 é depois de data1")
Trabalhando com só data (date) ou só hora (time)
from datetime import date, time
d = date.today() # Somente data
t = time(14, 30) # Somente hora
print(d) # 2025-06-21
print(t) # 14:30:00
Fuso horário (timezone)
O datetime também suporta fuso horário com tzinfo, mas isso pode ficar mais fácil com módulos como pytz ou zoneinfo (a partir do Python 3.9):
from datetime import timezone
agora_utc = datetime.now(timezone.utc)
print(agora_utc)
Timestamp
O timestamp é uma forma de representar um instante no tempo como um número inteiro ou decimal, geralmente contando segundos desde 1º de janeiro de 1970 às 00:00:00 UTC (conhecido como a Época Unix, ou Unix Epoch).
É uma medida precisa e padronizada que facilita o armazenamento, comparação e cálculo de datas e horários em sistemas computacionais.
Para que serve um timestamp
- Armazenar datas de forma compacta e sem ambiguidade.
- Comparar dois momentos facilmente (quem veio antes ou depois).
- Calcular a diferença de tempo entre eventos.
- Fazer ordenação cronológica (ex: logs, bancos de dados).
- Transmitir datas em APIs e sistemas distribuídos de forma universal (geralmente em UTC).
Obtendo um timestamp com Python
from datetime import datetime
agora = datetime.now()
timestamp = agora.timestamp()
print(timestamp) # Ex: 1729599326.894377
Esse número é a quantidade de segundos (com frações) desde a epoch. Se você quiser o timestamp inteiro (em segundos):
int(timestamp) # Ex: 1729599326
Convertendo timestamp de volta para datetime
from datetime import datetime
ts = 1729599326
data = datetime.fromtimestamp(ts)
print(data) # Ex: 2025-06-21 14:35:26 (horário local)
Para converter para horário UTC:
data_utc = datetime.utcfromtimestamp(ts)
print(data_utc) # Ex: 2025-06-21 17:35:26
Armazenar e comparar timestamps
Timestamps são ideais para:
- Armazenar tempos em banco de dados ou arquivos.
- Fazer cálculos simples com
>ou<para saber se um evento expirou, por exemplo. - Verificar tempo decorrido:
import time
inicio = time.time()
# ... alguma operação ...
fim = time.time()
print(f'Demorou {fim - inicio:.2f} segundos')
O timestamp() sempre considera a data como se estivesse em UTC, mesmo que o datetime tenha um fuso horário local. Para evitar confusão, use datetime.now(timezone.utc) ou zoneinfo para trabalhar com horários timezone-aware.