🌗 ← Índice

🐍 Python P06 — Arquivos e I/O


Data: 25/06/2026

Nível: Básico → Intermediário




Arquivos são a ponte entre teu código e o mundo real — logs, CSVs, JSONs, configurações. Hoje tu vai aprender a ler, escrever e processar arquivos do jeito Python: seguro, conciso e idiomático.




🎯 O que vamos aprender


  • `open()` — o canivete suíço de arquivos
  • `with` — o gerenciador de contexto que nunca esquece de fechar
  • Ler arquivos: `.read()`, `.readlines()`, iteração linha a linha
  • Escrever: `.write()` e `.writelines()`
  • CSV — processar dados tabulares com `csv.DictReader`
  • JSON — `json.load()` e `json.dump()`
  • Exemplo prático: processador de vendas
  • Exemplo prático: gerador de relatório



  • 📂 `open()` — Abrindo Arquivos


    A função open() retorna um file object. O modo define o que tu pode fazer:


    ModoSignificadoCria se não existe?

    |---|---|---|

    `'r'`Leitura (read)❌ Dá erro
    `'w'`Escrita (write) — **sobrescreve**
    `'a'`Acrescentar (append) — adiciona no final
    `'r+'`Leitura + escrita
    `'x'`Criação exclusiva — **dá erro se já existe**✅ (só se não existir)

    💡 **Regra de ouro:** Se não tem certeza se o arquivo existe, use `'a'` pra não perder dados.

    
    # Abrir pra leitura
    arquivo = open('dados.txt', 'r')
    conteudo = arquivo.read()
    arquivo.close()  # NUNCA esqueça de fechar!
    
    # Abrir pra escrita (cria ou sobrescreve)
    arquivo = open('saida.txt', 'w')
    arquivo.write('Olá, mundo!\n')
    arquivo.close()
    



    🛡️ `with` — O Jeito Seguro


    O with garante que o arquivo será fechado automaticamente — mesmo se der erro no meio do caminho.


    
    # ✅ Jeito idiomático (recomendado)
    with open('dados.txt', 'r') as f:
        conteudo = f.read()
    # Arquivo já está fechado aqui — sem risco de vazamento
    
    # ❌ Jeito manual (evite)
    f = open('dados.txt', 'r')
    conteudo = f.read()
    # Se der erro aqui em baixo, o close() nunca roda
    f.close()
    

    💡 **Sempre use `with`.** É mais curto, mais seguro e mais pythonico.



    📖 Lendo Arquivos


    Ler tudo de uma vez


    
    with open('dados.txt', 'r') as f:
        tudo = f.read()           # string com todo o conteúdo
        linhas = f.readlines()    # lista de strings (cada linha)
    

    Ler linha por linha (mais eficiente pra arquivos grandes)


    
    with open('dados.txt', 'r') as f:
        for linha in f:
            print(linha.strip())  # strip() remove \n e espaços
    

    Ler primeiras N linhas


    
    with open('vendas.csv', 'r') as f:
        cabecalho = f.readline()  # só a primeira linha
        primeiras_10 = [next(f) for _ in range(10)]
    



    ✍️ Escrevendo Arquivos


    
    # Escrever string
    with open('saida.txt', 'w') as f:
        f.write('Linha 1\n')
        f.write('Linha 2\n')
    
    # Escrever lista de strings
    linhas = ['a\n', 'b\n', 'c\n']
    with open('saida.txt', 'w') as f:
        f.writelines(linhas)
    
    # Append — adiciona sem apagar o que já existe
    with open('log.txt', 'a') as f:
        f.write(f'[INFO] Processado às {datetime.now()}\n')
    



    📊 CSV — Dados Tabulares


    O módulo csv da biblioteca padrão lida com vírgulas, aspas e escapes automaticamente.


    Ler CSV como dicionário (recomendado)


    
    import csv
    
    with open('vendas.csv', 'r', newline='', encoding='utf-8') as f:
        reader = csv.DictReader(f)
        for linha in reader:
            print(f"{linha['produto']}: R$ {linha['valor']}")
    

    Escrever CSV


    
    import csv
    
    dados = [
        {'nome': 'Hugo', 'linguagem': 'Python', 'nível': 6},
        {'nome': 'Ada',   'linguagem': 'Python', 'nível': 10},
    ]
    
    with open('devs.csv', 'w', newline='', encoding='utf-8') as f:
        writer = csv.DictWriter(f, fieldnames=['nome', 'linguagem', 'nível'])
        writer.writeheader()
        writer.writerows(dados)
    

    ⚠️ **Sempre use `newline=''`** ao abrir CSV no Python — evita linhas em branco no Windows.



    📦 JSON — Dados Estruturados


    JSON é o formato universal de APIs e arquivos de configuração.


    Ler JSON


    
    import json
    
    with open('config.json', 'r', encoding='utf-8') as f:
        dados = json.load(f)   # dict ou list
    
    print(dados['api_key'])
    

    Escrever JSON


    
    import json
    
    config = {
        'api_key': 'abc123',
        'timeout': 30,
        'retry': True
    }
    
    with open('config.json', 'w', encoding='utf-8') as f:
        json.dump(config, f, indent=2, ensure_ascii=False)
        # indent=2 → bonito e legível
        # ensure_ascii=False → mantém acentos (não escapa pra \uXXXX)
    



    🧪 Exemplo Prático 1: Processador de Vendas


    Lê um CSV de vendas e gera um relatório de total por produto.


    
    import csv
    from collections import defaultdict
    
    vendas_por_produto = defaultdict(float)
    
    with open('vendas.csv', 'r', encoding='utf-8') as f:
        reader = csv.DictReader(f)
        for linha in reader:
            produto = linha['produto']
            valor = float(linha['valor'])
            vendas_por_produto[produto] += valor
    
    # Gerar relatório
    with open('relatorio.txt', 'w', encoding='utf-8') as f:
        f.write("RELATÓRIO DE VENDAS\n")
        f.write("=" * 40 + "\n")
        for produto, total in sorted(vendas_por_produto.items()):
            f.write(f"{produto:<20} R$ {total:>10.2f}\n")
        f.write("=" * 40 + "\n")
        f.write(f"{'TOTAL':<20} R$ {sum(vendas_por_produto.values()):>10.2f}\n")
    
    print("✅ Relatório gerado: relatorio.txt")
    



    🧪 Exemplo Prático 2: Config em JSON


    
    import json
    from pathlib import Path
    
    CONFIG_FILE = Path('config.json')
    
    # Carregar config se existir, senão criar padrão
    if CONFIG_FILE.exists():
        with open(CONFIG_FILE, 'r') as f:
            config = json.load(f)
    else:
        config = {'version': '1.0', 'debug': False, 'api_url': 'http://localhost:5000'}
        with open(CONFIG_FILE, 'w') as f:
            json.dump(config, f, indent=2)
        print('✅ Arquivo de config criado!')
    
    print(f'API URL: {config["api_url"]}')
    



    📁 Pathlib — O Moderno


    pathlib é a forma moderna de lidar com caminhos no Python (substitui os.path).


    
    from pathlib import Path
    
    # Criar caminho
    pasta = Path('dados')
    pasta.mkdir(exist_ok=True)  # cria se não existe
    
    # Caminho de arquivo
    arquivo = pasta / 'vendas.csv'  # / junta caminhos!
    print(arquivo)  # dados/vendas.csv
    
    # Verificações
    if arquivo.exists():
        print(f'{arquivo} tem {arquivo.stat().st_size} bytes')
    
    # Ler e escrever com pathlib
    conteudo = Path('dados.txt').read_text(encoding='utf-8')
    Path('saida.txt').write_text('Olá!', encoding='utf-8')
    

    💡 `Path.read_text()` e `Path.write_text()` são atalhos que abrem, leem/escrevem e fecham — ideal pra arquivos pequenos.



    ✏️ Exercícios


    Bloco A — Leitura Básica


    1. Crie um arquivo nomes.txt com 5 nomes (um por linha). Escreva código que leia e imprima cada nome com "Olá, {nome}!".


    2. Leia o mesmo arquivo e retorne quantas linhas ele tem.


    Bloco B — Escrita


    3. Crie uma lista de dicionários com 3 produtos (nome e preço). Salve como produtos.json.


    4. Gere um arquivo tabuada.txt com a tabuada do 7 (de 1 a 10), uma linha por operação.


    Bloco C — CSV


    5. Crie um CSV alunos.csv com colunas nome,nota e 4 alunos. Escreva código que:

  • Leia o CSV
  • Calcule a média das notas
  • Imprima quem ficou acima da média

  • Bloco D — Integração


    6. Crie um script backup_config.py que:

  • Lê `config.json` (se existir)
  • Cria uma cópia com timestamp: `config_backup_20260625.json`
  • Se `config.json` não existir, cria um novo com valores padrão



  • ✅ Gabarito


    Clique para ver o gabarito


    Bloco A


    
    # 1. Ler nomes
    with open('nomes.txt', 'r', encoding='utf-8') as f:
        for nome in f:
            print(f'Olá, {nome.strip()}!')
    
    # 2. Contar linhas
    with open('nomes.txt', 'r', encoding='utf-8') as f:
        total = sum(1 for _ in f)
    print(f'Total de linhas: {total}')
    

    Bloco B


    
    # 3. Salvar JSON
    import json
    produtos = [
        {'nome': 'Teclado', 'preco': 150.00},
        {'nome': 'Mouse', 'preco': 80.00},
        {'nome': 'Monitor', 'preco': 900.00},
    ]
    with open('produtos.json', 'w', encoding='utf-8') as f:
        json.dump(produtos, f, indent=2, ensure_ascii=False)
    
    # 4. Tabuada
    with open('tabuada.txt', 'w', encoding='utf-8') as f:
        for i in range(1, 11):
            f.write(f'7 x {i:2} = {7 * i:2}\n')
    

    Bloco C


    
    # 5. Média de notas via CSV
    import csv
    
    with open('alunos.csv', 'r', encoding='utf-8') as f:
        reader = csv.DictReader(f)
        alunos = list(reader)
    
    notas = [float(a['nota']) for a in alunos]
    media = sum(notas) / len(notas)
    print(f'Média: {media:.1f}')
    
    for a in alunos:
        if float(a['nota']) > media:
            print(f'  ⬆ {a["nome"]}: {a["nota"]}')
    

    Bloco D


    
    # 6. Backup de config
    import json
    from pathlib import Path
    from datetime import datetime
    
    CONFIG = Path('config.json')
    if CONFIG.exists():
        dados = json.loads(CONFIG.read_text())
        backup = Path(f'config_backup_{datetime.now().strftime("%Y%m%d")}.json')
        backup.write_text(json.dumps(dados, indent=2))
        print(f'✅ Backup: {backup}')
    else:
        default = {'theme': 'dark', 'lang': 'pt-BR'}
        CONFIG.write_text(json.dumps(default, indent=2))
        print('✅ Config padrão criado')
    




    📌 Resumo para colar na testa


    
    open()  →  'r' (ler), 'w' (escrever/sobrescrever), 'a' (append), 'x' (criar novo)
    with    →  GERENCIADOR DE CONTEXTO — fecha sozinho, sempre use
    csv     →  DictReader / DictWriter pra dados tabulares
    json    →  json.load() / json.dump() pra APIs e configs
    pathlib →  Path('pasta/arquivo.txt').read_text() — o jeito moderno
    
    REGRA DE OURO:
      with open(...) as f:   ← sempre!
      newline=''             ← sempre em CSV!
      encoding='utf-8'       ← sempre pra evitar bugs com acentos!
    


    Próxima aula: P07 — Tratamento de Erros (try/except)