Path.walk: percorra diretórios com segurança

Publicado em: 10/10/2026
Tempo de leitura: 6 minutos
Código Python para percorrer pastas e arquivos com Path.walk

Path.walk() é um método da biblioteca pathlib para percorrer diretórios de forma estruturada, usando objetos Path em vez de strings. Ele simplifica tarefas como inventariar arquivos, localizar extensões, aplicar filtros, calcular tamanhos, remover diretórios vazios e organizar rotinas de backup. Neste guia, você aprenderá como usar Path.walk() com segurança, entender seus parâmetros e evitar armadilhas comuns.

O que é Path.walk()

O método walk() percorre uma árvore de diretórios e produz, a cada passo, uma tupla com três elementos: o diretório atual, a lista de subdiretórios e a lista de arquivos. A ideia é semelhante a os.walk(), mas integrada ao estilo orientado a objetos de pathlib.

from pathlib import Path

raiz = Path("projeto")

for diretorio, subdirs, arquivos in raiz.walk():
    print(diretorio)
    print(subdirs)
    print(arquivos)

O primeiro item é um objeto Path. Já os nomes em subdirs e arquivos são strings relativas ao diretório atual. Para obter o caminho completo, combine o diretório com o nome usando o operador /.

for diretorio, subdirs, arquivos in raiz.walk():
    for nome in arquivos:
        caminho = diretorio / nome
        print(caminho)

Por que usar pathlib em vez de strings

Trabalhar com Path deixa o código mais legível e portátil. Em vez de concatenar separadores manualmente, você usa o operador /. Métodos como suffix, name, stem, stat() e is_file() ficam disponíveis diretamente no objeto.

Essa abordagem combina bem com outras práticas de Python moderno. Consulte também nossos guias sobre importlib.resources no Python, fileinput no Python, linecache no Python e contextlib.chdir no Python.

Listando todos os arquivos

Um dos usos mais comuns é gerar uma lista de arquivos existentes em uma árvore. O exemplo abaixo ignora diretórios e reúne apenas arquivos.

from pathlib import Path

raiz = Path("dados")
arquivos_encontrados = []

for diretorio, subdirs, arquivos in raiz.walk():
    for nome in arquivos:
        arquivos_encontrados.append(diretorio / nome)

for caminho in arquivos_encontrados:
    print(caminho)

Para árvores muito grandes, evite acumular todos os caminhos em uma lista. Processe cada arquivo durante a própria iteração para reduzir o uso de memória.

Filtrando por extensão

Você pode filtrar arquivos por sufixo usando Path.suffix. Para comparações previsíveis, converta a extensão para minúsculas.

for diretorio, subdirs, arquivos in Path("logs").walk():
    for nome in arquivos:
        caminho = diretorio / nome
        if caminho.suffix.lower() == ".log":
            print(caminho)

Para várias extensões, use um conjunto, pois a consulta é eficiente e o código fica claro.

extensoes = {".csv", ".json", ".parquet"}

for diretorio, subdirs, arquivos in Path("dados").walk():
    for nome in arquivos:
        caminho = diretorio / nome
        if caminho.suffix.lower() in extensoes:
            processar(caminho)

Controlando a ordem da travessia

O parâmetro top_down define se a árvore é percorrida de cima para baixo ou de baixo para cima. O padrão é True. Nesse modo, o diretório pai aparece antes dos filhos.

for diretorio, subdirs, arquivos in Path("projeto").walk(top_down=True):
    print(diretorio)

Com top_down=False, os diretórios mais profundos são visitados primeiro. Esse modo é útil ao remover diretórios vazios, pois os filhos precisam ser tratados antes dos pais.

for diretorio, subdirs, arquivos in Path("temporario").walk(top_down=False):
    if not subdirs and not arquivos:
        diretorio.rmdir()

Ignorando pastas específicas

Quando top_down=True, você pode alterar a lista subdirs no lugar para impedir que certos diretórios sejam visitados. Isso é mais eficiente do que entrar na pasta e descartar os resultados depois.

ignoradas = {".git", ".venv", "node_modules", "__pycache__"}

for diretorio, subdirs, arquivos in Path("projeto").walk():
    subdirs[:] = [nome for nome in subdirs if nome not in ignoradas]
    for nome in arquivos:
        print(diretorio / nome)

A atribuição subdirs[:] modifica a lista original recebida pelo mecanismo de travessia. Criar apenas uma nova variável não altera o percurso.

Tratando erros com on_error

Permissões insuficientes, diretórios removidos durante a execução e falhas de entrada e saída podem interromper a travessia. O parâmetro on_error recebe uma função para tratar a exceção.

def registrar_erro(erro):
    print(f"Não foi possível acessar: {erro.filename}")

for diretorio, subdirs, arquivos in Path("/").walk(on_error=registrar_erro):
    pass

Em aplicações reais, prefira registrar o erro com contexto e continuar apenas quando isso for seguro. Não ignore silenciosamente todas as exceções, porque você pode gerar inventários incompletos sem perceber.

O comportamento relacionado a links simbólicos merece atenção. Seguir links para diretórios pode criar ciclos, especialmente quando um link aponta para um ancestral. Antes de habilitar esse comportamento, defina uma estratégia para evitar visitas repetidas.

Em rotinas críticas, registre os caminhos já visitados ou use identificadores do sistema de arquivos quando necessário. Também verifique se a aplicação deve atravessar links externos à raiz original. Em backups e scanners, isso pode causar leitura de locais inesperados.

Calculando o tamanho de uma árvore

O método pode ser usado para somar o tamanho dos arquivos. O exemplo trata arquivos que desaparecem entre a listagem e a chamada a stat().

from pathlib import Path

def tamanho_total(raiz: Path) -> int:
    total = 0
    for diretorio, subdirs, arquivos in raiz.walk():
        for nome in arquivos:
            caminho = diretorio / nome
            try:
                total += caminho.stat().st_size
            except OSError:
                continue
    return total

print(tamanho_total(Path("dados")))

Em ambientes concorrentes, a árvore pode mudar durante a execução. Por isso, resultados devem ser entendidos como uma fotografia aproximada, não como uma transação atômica.

Localizando arquivos grandes

Você pode combinar walk() com stat() para encontrar arquivos acima de um limite.

limite = 500 * 1024 * 1024

for diretorio, subdirs, arquivos in Path("arquivos").walk():
    for nome in arquivos:
        caminho = diretorio / nome
        try:
            if caminho.stat().st_size > limite:
                print(caminho)
        except OSError as erro:
            print(f"Falha ao ler {caminho}: {erro}")

Evite apagar arquivos automaticamente apenas com base no tamanho. Gere um relatório, valide o caminho e aplique regras de retenção explícitas.

Comparação com rglob()

rglob() é excelente quando você quer encontrar caminhos por padrão, como *.py. Já walk() oferece mais controle sobre a travessia, incluindo poda de diretórios, tratamento de erros e ordem de visita.

for caminho in Path("projeto").rglob("*.py"):
    print(caminho)

Use rglob() para buscas simples e walk() quando precisar tomar decisões sobre cada diretório.

Comparação com os.walk()

os.walk() continua válido e amplamente usado. A principal diferença é o estilo. Com Path.walk(), o diretório atual já é um objeto Path, o que reduz conversões e melhora a integração com outras operações da biblioteca.

Em projetos antigos, não é necessário migrar imediatamente. Faça a mudança quando ela simplificar o código e quando a versão mínima do Python usada pelo projeto oferecer suporte ao método.

Boas práticas de desempenho

Evite chamar stat() várias vezes para o mesmo arquivo. Se precisar de tamanho, datas e permissões, armazene o resultado em uma variável. Também filtre diretórios o mais cedo possível e processe arquivos em fluxo.

Para árvores muito grandes, considere limites de profundidade implementados por você. walk() não recebe diretamente um parâmetro de profundidade máxima, mas você pode comparar a quantidade de partes do caminho atual com a raiz e limpar subdirs quando atingir o limite.

raiz = Path("dados")
max_niveis = 3

for diretorio, subdirs, arquivos in raiz.walk():
    profundidade = len(diretorio.relative_to(raiz).parts)
    if profundidade >= max_niveis:
        subdirs.clear()

Segurança em operações destrutivas

Travessias de diretório costumam aparecer em scripts de limpeza. Antes de excluir, mover ou sobrescrever arquivos, valide se o caminho está dentro da raiz esperada. Use resolve() com cuidado e considere condições de corrida em sistemas multiusuário.

Uma estratégia segura é separar descoberta e execução. Primeiro produza um relatório; depois revise; por fim execute as alterações com logs e possibilidade de recuperação.

Compatibilidade

Como Path.walk() foi adicionado em versões recentes do Python, verifique a versão mínima do seu projeto. Para ambientes antigos, use os.walk() ou implemente uma camada de compatibilidade.

Consulte a documentação oficial de pathlib e a documentação de os.walk para detalhes atualizados de parâmetros e comportamento.

Conclusão

Path.walk() oferece uma forma moderna e expressiva de percorrer árvores de diretórios. Ele combina controle de travessia, integração com objetos Path, filtragem eficiente e tratamento de erros. Ao usá-lo, pense em permissões, links simbólicos, alterações concorrentes e impacto de operações destrutivas. Com esses cuidados, o método se torna uma base sólida para inventários, backups, validadores, pipelines de dados e ferramentas de manutenção.

Compartilhe:

Facebook
WhatsApp
Twitter
LinkedIn

Conteúdo do artigo

    Artigos relacionados

    Depuração de processo Python em terminal com código
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    pdb -p: depure processos Python em execução

    Aprenda a anexar o pdb a um processo Python em execução, inspecionar pilhas e diagnosticar travamentos com segurança.

    Ler mais

    Tempo de leitura: 6 minutos
    09/10/2026
    Código Python e representação de frações numéricas
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    fractions.from_number: converta números em frações

    Aprenda fractions.from_number no Python para converter números em frações exatas, controlar precisão e evitar arredondamentos inesperados.

    Ler mais

    Tempo de leitura: 5 minutos
    09/10/2026
    Desenvolvedor configurando servidor HTTPS e certificado TLS com Python
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    HTTPSServer: crie servidor HTTPS local no Python

    Aprenda HTTPSServer no Python para servir HTTPS localmente, configurar certificados, usar threads e entender limites de segurança.

    Ler mais

    Tempo de leitura: 5 minutos
    08/10/2026
    Arquivos protegidos representando extração segura de TAR com Python
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    tarfile extraction_filter: extraia TAR com segurança

    Aprenda tarfile extraction_filter no Python para extrair arquivos TAR com validação, segurança e controle de caminhos.

    Ler mais

    Tempo de leitura: 6 minutos
    08/10/2026
    Código Python exibindo avisos controlados com catch_warnings
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    catch_warnings: capture warnings em testes Python

    Aprenda catch_warnings no Python para capturar, testar e controlar avisos com filtros específicos e segurança.

    Ler mais

    Tempo de leitura: 5 minutos
    07/10/2026
    Código Python representando referências persistentes do pickle
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    pickle persistent_id: serialize referências externas

    Aprenda pickle persistent_id no Python para serializar referências externas com IDs estáveis, validação, segurança e compatibilidade.

    Ler mais

    Tempo de leitura: 5 minutos
    07/10/2026