---
title: "pathlib em Python: O Guia Prático para Manipular Caminhos e Arquivos"
url: "https://python.dev.br/blog/python-pathlib-manipulacao-caminhos-arquivos/"
markdown_url: "https://python.dev.br/blog/python-pathlib-manipulacao-caminhos-arquivos.MD"
description: "Aprenda a usar o módulo pathlib do Python para manipular caminhos, listar arquivos com glob e rglob, ler e escrever com read_text e write_text, criar e remover pastas e migrar do os.path. Guia prático em português brasileiro com exemplos de automação de arquivos."
date: "2026-07-18"
author: "Equipe Python Brasil"
---

# pathlib em Python: O Guia Prático para Manipular Caminhos e Arquivos

Aprenda a usar o módulo pathlib do Python para manipular caminhos, listar arquivos com glob e rglob, ler e escrever com read_text e write_text, criar e remover pastas e migrar do os.path. Guia prático em português brasileiro com exemplos de automação de arquivos.


O `pathlib` é o módulo da biblioteca padrão do Python para trabalhar com caminhos de arquivos e pastas. Ele substitui, com vantagem, as velhas funções do `os.path` (`os.path.join`, `os.path.exists`, `os.path.basename`), oferecendo um objeto `Path` com métodos e atributos prontos para as operações mais comuns do dia a dia: listar arquivos, ler e escrever conteúdo, criar pastas, percorrer subdiretórios com `glob` e montar caminhos de forma legível. Desde o Python 3.12 o próprio `os.path` é implementado internamente sobre o `pathlib`, o que reforça o `pathlib` como a **API oficial e moderna** para caminhos.

Se você já automatiza [planilhas CSV](/blog/python-csv-leitura-escrita-arquivos/), [documentos Word](/blog/python-e-word-python-docx/) ou [arquivos ZIP](/blog/python-zipfile-shutil-comprimir-extrair/), dominar o `pathlib` é o que transforma scripts avulsos em pipelines robustos que percorrem pastas inteiras. Este guia parte do objeto `Path` e chega a receitas práticas de automação brasileira, com uma [comparação direta contra o `os.path`](#pathlib-vs-os-path-qual-usar-em-2026) no final.

## Criando um caminho com `Path`

Tudo começa importando `Path` e construindo um caminho. O `pathlib` usa o operador `/` para juntar partes — o que é muito mais legível do que `os.path.join("a", "b", "c.txt")`:

```python
from pathlib import Path

# Caminho relativo na pasta do projeto
pasta_dados = Path("dados")
arquivo = pasta_dados / "vendas" / "2026.csv"

print(arquivo)        # dados/vendas/2026.csv (no Linux/macOS)
                     # dados\vendas\2026.csv (no Windows)
print(type(arquivo))  # <class 'pathlib.PosixPath'>  (ou WindowsPath no Windows)
```

Repare em três detalhes importantes:

1. O operador `/` funciona mesmo entre um `Path` e uma `str` — ele monta o caminho na sintaxe correta do sistema operacional.
2. No Linux e macOS você recebe um `PosixPath`; no Windows, um `WindowsPath`. Você não escolhe: o `pathlib` decide sozinho, e o **mesmo código roda nas duas plataformas**.
3. Para transformar um caminho relativo em absoluto (com a pasta raiz resolvida), use `.resolve()`:

```python
print(Path("dados/2026.csv").resolve())
# /home/maria/projetos/dados/2026.csv
```

## Atributos de um caminho: nome, extensão, pasta-pai

Um dos grandes ganhos do `pathlib` é acessar pedaços do caminho por atributos claros, sem ficar cortando string:

```python
p = Path("/home/maria/projetos/dados/2026.csv")

p.name        # '2026.csv'        — nome do arquivo
p.stem        # '2026'            — nome sem a extensão
p.suffix      # '.csv'            — extensão (com o ponto)
p.suffixes    # ['.tar', '.gz']   — lista de extensões (para .tar.gz)
p.parent      # /home/maria/projetos/dados
p.parents[0]  # mesmo que .parent
p.parents[1]  # /home/maria/projetos
p.parts       # ('/', 'home', 'maria', 'projetos', 'dados', '2026.csv')
p.anchor      # '/'  (ou 'C:\\' no Windows)
```

Esses atributos resolvem, sem esforço, tarefas chatas como trocar a extensão de um arquivo (`p.with_suffix(".txt")`) ou pegar só o nome da pasta:

```python
p.with_suffix(".txt")   # /home/maria/projetos/dados/2026.txt
p.with_name("resumo.md") # /home/maria/projetos/dados/resumo.md
```

## Verificações: o arquivo existe? É arquivo ou pasta?

Antes de ler ou apagar qualquer coisa, verifique. O `pathlib` traz os métodos booleanos mais usados:

```python
arquivo = Path("notas_fiscais/2026-07.xml")

arquivo.exists()    # True/False — o caminho existe no disco?
arquivo.is_file()   # é um arquivo (não uma pasta)?
arquivo.is_dir()    # é uma pasta?
arquivo.is_absolute() # é um caminho absoluto?
```

Para um [script de automação](/blog/automatizacao-com-python/) que processa arquivos, o padrão defensivo é:

```python
arquivo = Path("config.yaml")
if not arquivo.exists():
    raise FileNotFoundError(f"Configuração não encontrada: {arquivo}")
```

## Listando arquivos: `iterdir`, `glob` e `rglob`

Esta é a funcionalidade que mais economiza tempo. Para percorrer o conteúdo de uma pasta:

```python
pasta = Path("relatorios")

# Tudo que está diretamente dentro da pasta (arquivos e subpastas)
for item in pasta.iterdir():
    print(item.name)
```

Para filtrar por padrão, use `.glob()`. Ele aceita curingas como `*` e `?`, mas **não desce** nas subpastas:

```python
# Apenas arquivos .csv no primeiro nível
for csv in pasta.glob("*.csv"):
    print(csv)
```

Para percorrer a pasta **e todas as subpastas** recursivamente, use `.rglob()`:

```python
# Todos os arquivos .xlsx em qualquer nível de profundidade
for planilha in pasta.rglob("*.xlsx"):
    print(planilha)
```

É com `.rglob()` que você constrói, em três linhas, um processador de [arquivos do escritório](/blog/python-e-excel-openpyxl/) inteiro:

```python
from pathlib import Path
import csv

pasta = Path("vendas")
for arquivo in pasta.rglob("*.csv"):
    with arquivo.open(encoding="utf-8") as f:
        linhas = sum(1 for _ in f)
    print(f"{arquivo.name}: {linhas} linhas")
```

## Lendo e escrevendo arquivos com `read_text` e `write_text`

Para ler ou gravar um arquivo inteiro de uma vez, o `pathlib` oferece atalhos que dispensam o `open` com `with`:

```python
p = Path("config.txt")

# Escrever (sobrescreve o arquivo)
p.write_text("timeout=30\n", encoding="utf-8")

# Ler
conteudo = p.read_text(encoding="utf-8")
print(conteudo)
```

Esses métodos abrem, leem/escrevem e fecham o arquivo automaticamente. Para **processar linha a linha**, gravar incrementalmente ou lidar com arquivos muito grandes, continue usando `.open()` (equivalente ao `open` tradicional dentro de um `with`) — veja o tutorial de [manipulação de arquivos](/blog/manipulacao-de-arquivos-python/) e o de [context managers com with](/blog/context-managers-python-with/).

```python
# Leitura linha a linha para arquivos grandes
with Path("log.txt").open(encoding="utf-8") as f:
    for linha in f:
        if "ERRO" in linha:
            print(linha.strip())
```

## Criando, movendo, copiando e removendo

Operações de sistema de arquivos ficam expressivas no `pathlib`:

```python
from pathlib import Path
import shutil

pasta = Path("saida")
arquivo = pasta / "relatorio.txt"

# Criar uma pasta (exist_ok=True evita erro se já existir)
pasta.mkdir(parents=True, exist_ok=True)

# Criar um arquivo vazio (se não existir)
arquivo.touch()

# Copiar (o pathlib delega ao shutil para cópia)
shutil.copy("entrada.txt", arquivo)

# Renomear / mover
arquivo.rename(pasta / "relatorio_final.txt")

# Remover o arquivo
(pasta / "relatorio_final.txt").unlink()

# Remover a pasta (precisa estar vazia)
pasta.rmdir()
```

O `mkdir(parents=True, exist_ok=True)` equivale a `mkdir -p` do Linux: cria pastas intermediárias e não reclama se a pasta já existe. É a forma recomendada de preparar diretórios de saída.

## Receita brasileira: organizar notas fiscais por mês

Um caso de uso concreto que une tudo: você recebe dezenas de XMLs de NF-e soltos numa pasta e quer organizá-los em subpastas por mês de emissão. Com `pathlib` e [tratamento de datas](/blog/datas-e-horas-python-datetime-zoneinfo/), o script fica enxuto:

```python
from pathlib import Path
from datetime import datetime

pasta_entrada = Path("xmls_recebidos")
pasta_saida = Path("xmls_organizados")

for xml in pasta_entrada.glob("*.xml"):
    # Extrai a data do nome (padrão: NF_2026-07-18_12345.xml)
    try:
        data_str = xml.stem.split("_")[1]            # '2026-07-18'
        mes = datetime.strptime(data_str, "%Y-%m-%d").strftime("%Y-%m")
    except (IndexError, ValueError):
        mes = "sem_data"

    destino = pasta_saida / mes
    destino.mkdir(parents=True, exist_ok=True)
    xml.rename(destino / xml.name)                    # move o arquivo

print("Organização concluída.")
```

O mesmo molde serve para separar [comprovantes em PDF](/blog/python-gerar-pdf-relatorios/), agrupar imagens de produtos por SKU ou consolidar [planilhas](/blog/python-para-automacao-de-planilhas/) por filial. Sempre que você precisar "varrer uma pasta e reagrupar por regra", comece com `.rglob()` + `.mkdir()` + `.rename()`.

## pathlib vs os.path: qual usar em 2026?

Se você mantém código legado com `os.path`, não precisa reescrever — as duas APIs coexistem. Em **projetos novos**, porém, o `pathlib` é a recomendação oficial da documentação do Python. A tabela resume as equivalências mais comuns:

| Operação | `os.path` (legado) | `pathlib` (moderno) |
| --- | --- | --- |
| Juntar caminho | `os.path.join("a", "b.txt")` | `Path("a") / "b.txt"` |
| Caminho absoluto | `os.path.abspath(p)` | `p.resolve()` |
| Existe? | `os.path.exists(p)` | `p.exists()` |
| É arquivo? | `os.path.isfile(p)` | `p.is_file()` |
| Nome do arquivo | `os.path.basename(p)` | `p.name` |
| Pasta-pai | `os.path.dirname(p)` | `p.parent` |
| Extensão | `os.path.splitext(p)[1]` | `p.suffix` |
| Nome sem extensão | `os.path.splitext(p)[0]` | `p.stem` |
| Tamanho em bytes | `os.path.getsize(p)` | `p.stat().st_size` |
| Listar pasta | `os.listdir(pasta)` | `pasta.iterdir()` |
| Busca recursiva | `os.walk(pasta)` | `pasta.rglob("*")` |

A regra prática: se você está escrevendo a versão moderna de um script, use `pathlib`; se está lendo um tutorial antigo com `os.path`, entenda a equivalência mas prefira converter para `pathlib` ao refatorar.

## Boas práticas

- **Sempre informe o `encoding`** ao ler ou gravar texto (`read_text(encoding="utf-8")`). No Windows, o padrão costuma ser `cp1252`; em arquivos com acentos, o UTF-8 evita `UnicodeDecodeError`.
- **Use `.resolve()` antes de comparar caminhos** absolutos — dois caminhos diferentes na string podem apontar para o mesmo arquivo depois de resolvidos.
- **Prefira `.glob`/`.rglob` ao `os.walk`** para buscas por padrão; reserve `os.walk` para percorrimentos com lógica de filtro complexa.
- **Não corte extensões com string slicing.** Use `.suffix` e `.with_suffix()` — eles respeitam arquivos como `.tar.gz`.
- **Valide a entrada antes de mover/apagar.** Um `if not arquivo.exists()` custa pouco e evita acidentes em automações que rodam em produção.

## Conclusão

O `pathlib` é uma daquelas partes do Python que, uma vez aprendidas, mudam a forma como você escreve código para sempre. O objeto `Path` concentra nome, extensão, pasta-pai e verificação de existência em atributos legíveis; `.glob` e `.rglob` substituem loops inteiros de `os.walk`; e `read_text`/`write_text` deixam a leitura e escrita simples em uma linha. Para qualquer automação que envolva arquivos — da organização de notas fiscais ao processamento de planilhas em lote — comece pelo `pathlib`.

Para continuar a sequência de fundamentos da biblioteca padrão, veja como combinar `pathlib` com [collections](/blog/collections-python-guia-completo/) para contar e agrupar arquivos, com [expressões regulares](/blog/expressoes-regulares-python/) para renomear em massa, e com o [módulo subprocess](/blog/python-subprocess-comandos-externos/) para chamar ferramentas externas sobre os caminhos encontrados.

## Perguntas frequentes

### O pathlib vem instalado com o Python ou preciso instalar algo?

O `pathlib` faz parte da biblioteca padrão do Python desde a versão 3.4 e não precisa ser instalado com o pip — basta fazer `from pathlib import Path`. A partir do Python 3.12 o módulo `os.path` é implementado internamente sobre o `pathlib`, o que reforça o `pathlib` como a API oficial e moderna para trabalhar com caminhos.

### Qual a diferença entre pathlib e os.path?

O `os.path` manipula caminhos como strings e usa funções soltas como `os.path.join` e `os.path.exists`. O `pathlib` representa o caminho como um objeto `Path`, com métodos e atributos encadeáveis (`p.suffix`, `p.parent`, `p.read_text()`) e suporta o operador `/`. O resultado é um código mais legível e orientado a objetos; em projetos novos, prefira `pathlib`.

### Como listar apenas arquivos .csv de uma pasta e suas subpastas com pathlib?

Use `Path('pasta').rglob('*.csv')`, que percorre a pasta e todas as subpastas. Para listar só o primeiro nível, sem descer nas subpastas, use `Path('pasta').glob('*.csv')`. Ambos retornam objetos `Path` que podem ser iterados diretamente com um `for`.

### Como o pathlib lida com caminhos no Windows e no Linux ao mesmo tempo?

O `pathlib` normaliza o separador automaticamente: ao usar o operador `/` ou `Path()`, ele usa a barra correta do sistema (`\` no Windows, `/` no Linux e macOS). O mesmo código funciona nas duas plataformas sem `if`. Para um caminho absoluto, use `Path.resolve()`, que resolve o caminho completo no sistema atual.

### read_text e write_text substituem o open com with?

Para a leitura e escrita simples de um arquivo inteiro, sim. `Path('arquivo.txt').read_text(encoding='utf-8')` abre, lê e fecha o arquivo automaticamente. Para processar linha a linha, gravar incrementalmente ou lidar com arquivos muito grandes, continue usando `open` com `with`, como no tutorial de [manipulação de arquivos](/blog/manipulacao-de-arquivos-python/).
