Menu

Verificar se um arquivo existe em Python: os.path, pathlib e try/except

Três formas de verificar se um arquivo existe em Python: os.path.exists e isfile, Path.exists e is_file do pathlib, e abrir o arquivo dentro de try/except FileNotFoundError.

Esta página tem editores executáveis - edite, execute e veja a saída na hora.

A resposta curta

Para verificar se um arquivo existe, use os.path.isfile() da biblioteca padrão. Ela retorna True quando o caminho aponta para um arquivo comum que existe e False caso contrário. Nunca lança erro para um caminho que não existe.

Os caminhos são relativos à pasta onde o programa roda (o diretório de trabalho atual), a menos que você passe um caminho absoluto como /home/ada/notes.txt ou C:\Users\Ada\notes.txt.

O resto desta página cobre as outras formas de fazer a pergunta, como elas diferem e o caso em que você não deveria fazê-la.

os.path.exists vs isfile vs isdir

O módulo os.path tem três verificações parecidas, e elas respondem perguntas um pouco diferentes:

FunçãoRetorna True quando o caminho é
os.path.exists(p)qualquer coisa que exista: um arquivo, um diretório ou um link simbólico válido
os.path.isfile(p)um arquivo comum que existe
os.path.isdir(p)um diretório que existe

A diferença aparece assim que um diretório entra na história:

Saída:

reports True False True
reports/summary.txt True True False
reports/old.txt False False False

os.path.exists("reports") é True mesmo sendo reports uma pasta. Se o seu código vai ler o caminho como arquivo, exists é a verificação errada: um diretório passaria nela, e open("reports") falharia depois (com IsADirectoryError no Linux e no macOS, PermissionError no Windows). Escolha isfile quando você quer um arquivo e isdir quando quer uma pasta.

Mais dois detalhes sobre essas três funções de os.path:

  • Um link simbólico é seguido. Um link que aponta para um arquivo real conta como arquivo; um link quebrado (o alvo sumiu) retorna False nas três.
  • Se o Python não tem permissão para olhar dentro de uma pasta, a verificação retorna False em vez de lançar PermissionError. False quer dizer "não encontrado ou inacessível", não estritamente "não existe".

Verificando com pathlib

pathlib é a API de caminhos orientada a objetos da biblioteca padrão, e a maior parte do código novo usa ela. Um objeto Path tem as mesmas três verificações como métodos:

Path.exists(), Path.is_file() e Path.is_dir() se comportam como os.path.exists, isfile e isdir. O operador / junta partes do caminho com o separador certo para o sistema operacional, então folder / "summary.txt" funciona igual no Windows, no macOS e no Linux. Veja manipulação de arquivos para ler e escrever por meio de objetos Path.

Qual usar? Se o resto do seu código já passa objetos Path de um lado para outro, fique com o pathlib. Se você trabalha com strings simples e funções de os, os.path.isfile é igualmente correto. As respostas são as mesmas.

Por que verificar antes pode ser a escolha errada

O motivo mais comum para verificar se um arquivo existe é abri-lo logo depois:

import os

if os.path.isfile("config.txt"):
    with open("config.txt") as f:      # the file might be gone by now
        settings = f.read()
else:
    settings = ""

Isso tem uma brecha. Entre a chamada de isfile() e a chamada de open(), outro programa, outra thread ou o próprio usuário pode apagar ou renomear o arquivo. A verificação disse True, a abertura falha mesmo assim, e o programa quebra com FileNotFoundError de qualquer jeito. Essa brecha se chama condição de corrida, ou "time of check to time of use" (momento da verificação contra momento do uso). É rara no seu notebook e bem menos rara num servidor movimentado onde vários processos dividem uma pasta.

A solução é pular a verificação separada e deixar o próprio open() ser a verificação. O Python lança FileNotFoundError quando o arquivo não existe, e você trata isso no except:

Saída:

theme=dark
(no settings file, using defaults)

Agora há uma operação em vez de duas, então não há corrida possível. Esse estilo tem nome na comunidade Python: EAFP, "easier to ask forgiveness than permission" (é mais fácil pedir perdão do que permissão). O estilo oposto, verificar antes, é LBYL, "look before you leap" (olhe antes de pular). O Python prefere EAFP para trabalhar com arquivos porque o sistema operacional é o único que sabe a resposta no momento em que você abre o arquivo.

FileNotFoundError não é a única coisa que pode dar errado. Um caminho que é um diretório lança IsADirectoryError (PermissionError no Windows), e um arquivo que você não pode ler lança PermissionError. As três são subclasses de OSError, então except OSError: pega de uma vez todos os casos de "não consegui abrir". A página de exceções explica como escolher entre capturar um erro específico e capturar uma família inteira.

Quando uma verificação simples basta

Verificar antes não é errado em todos os casos. É a ferramenta certa quando você só precisa da resposta e não vai mexer no arquivo na linha seguinte:

  • escolher qual mensagem mostrar ("3 jogos salvos encontrados")
  • validar um caminho que o usuário digitou antes de começar um trabalho longo
  • pular um trabalho que já foi feito, quando uma resposta desatualizada só custa uma repetição

A regra prática: se você vai abrir, ler, escrever ou apagar o arquivo, faça isso dentro de try. Se só quer saber, isfile() ou Path.is_file() servem.

Criar um arquivo só se ele não existir

A pergunta inversa também aparece: "escreva este arquivo, mas nunca sobrescreva um que já existe". A versão óbvia tem a mesma corrida de antes:

if not os.path.exists("report.txt"):
    with open("report.txt", "w") as f:   # another process may create it first
        f.write("new report\n")

O modo "x" (criação exclusiva) faz os dois passos em um. Ele cria o arquivo, ou lança FileExistsError se o nome já estiver ocupado:

Saída:

attempt 1: created report.txt
attempt 2: report.txt already exists, left it alone

Para pastas, os.makedirs(path, exist_ok=True) e Path(path).mkdir(parents=True, exist_ok=True) criam o diretório e qualquer pasta pai que falte, e não fazem nada se ele já existir. Não precisa chamar isdir() antes.

Erros comuns

  • Usar exists() quando você quer um arquivo. Um diretório com o mesmo nome passa na verificação. Use isfile() ou Path.is_file().
  • Esquecer de onde partem os caminhos relativos. "data.txt" é procurado no diretório de trabalho atual, que é de onde você iniciou o programa, não necessariamente a pasta onde está o script. Para achar um arquivo ao lado do script, monte o caminho a partir de Path(__file__).parent.
  • Verificar e depois abrir. O arquivo pode mudar nesse meio tempo. Abra dentro de try e trate FileNotFoundError.
  • Capturar qualquer exceção. except Exception: em volta de open() também esconde erros de digitação e bugs no código que lê o arquivo. Capture FileNotFoundError ou OSError.

Perguntas frequentes

Como verifico se um arquivo existe em Python?

Importe os e chame os.path.isfile("data.txt"), que retorna True apenas para um arquivo comum que existe. Com pathlib é Path("data.txt").is_file(). Use os.path.exists() ou Path.exists() quando um diretório com esse nome também deve contar.

Qual a diferença entre os.path.exists e os.path.isfile?

os.path.exists(p) é True para qualquer coisa naquele caminho: um arquivo, um diretório ou um link simbólico que aponta para algo real. os.path.isfile(p) é True apenas para um arquivo comum, então retorna False para um diretório. os.path.isdir(p) é o equivalente para diretórios.

Devo verificar se um arquivo existe antes de abri-lo?

Normalmente não. O arquivo pode ser apagado ou criado entre a verificação e a chamada de open(), então a verificação não garante nada. Abra o arquivo direto dentro de try e trate FileNotFoundError no except. Uma verificação separada é o certo quando você só precisa da resposta, por exemplo para decidir qual mensagem mostrar.

Como crio um arquivo só se ele não existir?

Abra com o modo "x": open("report.txt", "x"). O Python cria o arquivo, ou lança FileExistsError se já houver algo com esse nome. A verificação e a criação acontecem em um passo só, então nenhum outro programa consegue se meter entre as duas.

Coddy programming languages illustration

Aprenda a programar com o Coddy

COMEÇAR