7 Maneiras de Verificar Arquivos/Pastas em Python (Guia Completo)

Explorando a Verificação de Arquivos e Diretórios em Python

A biblioteca padrão do Python oferece uma vasta gama de recursos essenciais para o desenvolvimento de soluções eficazes. Neste guia, vamos investigar diferentes abordagens para determinar a existência de arquivos ou diretórios, utilizando exclusivamente os módulos incorporados da linguagem.

Em programas de linha de comando (CLI), a confirmação da presença de arquivos e scripts nos locais corretos é de suma importância. A ausência de um arquivo específico no momento da execução pode comprometer a funcionalidade de um programa.

Hoje, vamos apresentar diversas maneiras concisas de verificar se um arquivo ou diretório existe no ambiente Python.

Preparando o Terreno

Antes de começarmos, certifique-se de que o Python 3 está instalado no seu sistema. Para confirmar, execute o seguinte comando no terminal:

python --version
  # Python 3.9.5 (exemplo de resultado)

Se você possui uma versão 2.x, use o comando “python3”. Caso não tenha o Python 3 instalado, consulte nosso guia de instalação.

Para acompanhar este tutorial, precisaremos de alguns arquivos de teste. Crie os seguintes elementos:

touch arquivo_teste.txt
  mkdir diretorio_teste/
  touch diretorio_teste/outro_arquivo.txt

Estes comandos irão gerar um arquivo para testes, um diretório de teste e um arquivo adicional dentro deste diretório. O conteúdo dos arquivos não é relevante, pois não será utilizado.

Observação: Se estiver utilizando o Windows, crie esta estrutura de arquivos através do gerenciador de arquivos.

Além disso, utilizaremos o Ipython como nosso shell interativo do Python, proporcionando uma interface amigável. Esta etapa é opcional, mas recomendada.

pip install ipython

Após a instalação, inicie o shell digitando “ipython”.

Com tudo configurado, vamos explorar as diferentes maneiras de verificar a existência de arquivos e diretórios em Python.

Utilizando “try”, “open” e “except”

Esta abordagem é bastante direta. Ao tentar abrir um arquivo inexistente, o Python lançará um erro FileNotFoundError.

In [1]: open('arquivo-inexistente.txt')
  ---------------------------------------------------------------------------
  FileNotFoundError: [Errno 2] No such file or directory: 'arquivo-inexistente.txt'
  

Podemos aproveitar essa situação para tratar a exceção caso o arquivo desejado não seja encontrado.

In [2]: try:
    ...:     arquivo = open('arquivo-inexistente.txt')
    ...:     print(arquivo) # Manipulador de arquivo
    ...:     arquivo.close()
    ...: except FileNotFoundError:
    ...:     print('O arquivo que você está procurando não existe.')
    ...:     exit()
    ...: 
  O arquivo que você está procurando não existe.
  

No código acima, exibimos uma mensagem personalizada e interrompemos a execução do programa caso o arquivo não exista.

Note que a função “exit()” só será executada se a exceção for acionada. Vejamos o que acontece quando o arquivo realmente existe:

In [2]: try:
    ...:     arquivo = open('arquivo_teste.txt')
    ...:     print(arquivo) # Manipulador de arquivo
    ...:     arquivo.close()
    ...: except FileNotFoundError:
    ...:     print('O arquivo que você está procurando não existe.')
    ...:     exit()
    ...: 
  <_io.TextIOWrapper name="arquivo_teste.txt" mode="r" encoding='UTF-8'>
  

Observe que estamos fechando o arquivo logo após abri-lo. Isso é considerado uma boa prática, conforme a documentação do Python.

A chamada de file.write() sem o uso da palavra-chave with, ou a falta de chamada de file.close(), pode impedir que os argumentos de file.write() sejam totalmente gravados no disco, mesmo que o programa termine sem erros.

Apesar de não estarmos gravando no arquivo, é crucial fechá-lo, pois essa prática evita diversos problemas de desempenho.

Para evitar o fechamento manual do arquivo, podemos usar o gerenciador de contexto “with”. Ele gerencia a alocação e liberação de recursos, dispensando o fechamento manual.

In [3]: try:
    ...:     with open('arquivo_teste.txt') as arquivo:
    ...:         print(arquivo)
    ...:         # Não há necessidade de fechar o arquivo
    ...: except FileNotFoundError:
    ...:     print('O arquivo que você está procurando não existe.')
    ...:     exit()
    ...: 
    ...: 
  <_io.TextIOWrapper name="arquivo_teste.txt" mode="r" encoding='UTF-8'>
  

Embora eficaz na escrita de arquivos, este método se torna ineficiente para a simples verificação da existência de um arquivo. Vamos explorar outras opções.

Função os.path.exists()

O módulo os fornece diversas funcionalidades para interagir com o sistema operacional. Para verificar a existência de um arquivo ou diretório, podemos utilizar a função “path.exists()”, que recebe o caminho do arquivo ou diretório como argumento e retorna um booleano indicando sua existência.

Nota: Um caminho é o local exclusivo de um arquivo ou diretório em um sistema de arquivos.

Em Python, o submódulo os.path contém funções específicas para manipulação de caminhos de arquivos. Essas funções aceitam caminhos como strings ou bytes, permitindo o uso de caminhos absolutos (por exemplo):

/home/usuario/.bashrc

ou caminhos relativos, dependendo do diretório em que o script é executado:

.bashrc
  # Executando o script na pasta pessoal

Aqui estão alguns exemplos utilizando a função os.path.exists(), executados no mesmo diretório dos arquivos de teste:

In [1]: import os

  In [2]: os.path.exists('arquivo_teste.txt')
  Out[2]: True

  In [3]: os.path.exists('diretorio_teste')
  Out[3]: True

  In [4]: os.path.exists('nao-existo')
  Out[4]: False

Como podemos observar, a função retorna “True” para o arquivo “arquivo_teste.txt” e o diretório “diretorio_teste”, e “False” para o arquivo inexistente.

Função os.path.isfile()

Se você precisa verificar apenas a existência de um arquivo (e não de um diretório), utilize a função “os.path.isfile()”.

In [1]: import os

  In [2]: os.path.isfile('arquivo_teste.txt')
  Out[2]: True

  In [3]: os.path.isfile('diretorio_teste/')
  Out[3]: False

  In [4]: os.path.isfile('nao-existo')
  Out[4]: False

  In [5]: os.path.isfile('diretorio_teste/outro_arquivo.txt')
  Out[5]: True
  

Observação: No UNIX, todos os diretórios terminam com uma barra (/), enquanto no Windows usamos uma barra invertida (\).

No código acima, a função “isfile()” retorna “False” em duas situações:

  • “diretorio_teste/” é um diretório, e não um arquivo. Embora no Linux tudo seja um descritor de arquivo, o Python trata diretórios de forma distinta por conveniência (a tentativa de abrir um diretório resulta em “IsADirectoryError”).
  • “nao-existo” aponta para um arquivo que não existe.

Função os.path.isdir()

Para verificar a existência de um diretório, use a função “os.path.isdir()”. Ela retorna “True” apenas se o caminho fornecido apontar para um diretório.

In [1]: import os

  In [2]: os.path.isdir('arquivo_teste.txt')
  Out[2]: False

  In [3]: os.path.isdir('diretorio_teste')
  Out[3]: True

  In [4]: os.path.isdir('outro_arquivo.txt')
  Out[4]: False
  

Note que os exemplos acima retornam “False” mesmo quando o caminho aponta para um arquivo existente.

Módulo glob

O módulo glob oferece funções para trabalhar com padrões de nome de arquivos (semelhantes aos do shell Unix). A função glob.glob() pode ser utilizada para verificar se um arquivo corresponde a um padrão no diretório atual.

In [1]: import glob

  In [2]: glob.glob('arquivo_teste.txt')
  Out[2]: ['arquivo_teste.txt']

  In [3]: glob.glob('diretorio_teste')
  Out[3]: ['diretorio_teste']
  

Neste código, o padrão passado para a função “glob” é uma string normal representando o caminho do arquivo e do diretório de teste. Como ambos os caminhos existem, a função retorna uma lista com os nomes dos caminhos correspondentes.

Observação: Se o padrão não corresponder a nenhum caminho, a função retornará uma lista vazia.

Como podemos usar padrões com a função “glob”, vamos explorar algumas de suas vantagens:

O código abaixo obtém todos os caminhos de arquivo com extensão “.txt” e “.py”, respectivamente:

In [4]: glob.glob('*.txt')
  Out[4]: ['arquivo_teste.txt']

  In [5]: glob.glob('*.py')
  Out[5]:
  ['pathlib_existe.py',
  'list_dir.py',
  'glob_file.py',
  'open_except.py',
  'subprocess_teste.py',
  'isfile.py',
  'existe.py',
  'isdir.py']

Utilizando a Classe Path

A classe Path oferece uma interface clara para trabalhar com caminhos de arquivos como objetos, sendo uma das melhores opções nesse sentido.

Instâncias da classe Path possuem todos os métodos necessários para obter informações sobre um determinado caminho, incluindo funcionalidades semelhantes às abordagens anteriores.

Observação: A biblioteca “pathlib” requer o Python 3.4 ou superior.

Métodos Path que você utilizará:

Verificando a existência de um caminho

In [1]: from pathlib import Path

  In [2]: Path('arquivo_teste.txt').exists()
  Out[2]: True

  In [3]: Path('nao-existo.txt').exists()
  Out[3]: False

  In [4]: Path('diretorio_teste').exists()
  Out[4]: True
  

Essa função opera de forma similar a “os.path.exists()”.

Verificando se o caminho aponta para um arquivo

In [5]: Path('arquivo_teste.txt').is_file()
  Out[5]: True

  In [6]: Path('diretorio_teste').is_file()
  Out[6]: False
  

Essa função equivale a “os.path.isfile()”.

Verificando se o caminho aponta para um diretório

In [7]: Path('arquivo_teste.txt').is_dir()
  Out[7]: False

  In [8]: Path('diretorio_teste').is_dir()
  Out[8]: True
  

Essa função corresponde a “os.path.isdir()”.

Módulo subprocess

Se você é um entusiasta do módulo “subprocess”, esta opção pode lhe interessar. É possível determinar a existência de um arquivo ou diretório utilizando o comando test.

Observação: O comando “test” funciona apenas em sistemas Unix.

Os seguintes sinalizadores do comando “test” serão úteis:

  • “test -e”: Verifica a existência de um caminho.
  • “test -f”: Verifica a existência de um arquivo.
  • “test -d”: Verifica a existência de um diretório.

Para explorar outros sinalizadores do comando “test”, consulte o manual executando:

man test

Verificando um caminho com o módulo subprocess

O código abaixo verifica a existência de um caminho comparando o código de retorno do subprocesso com 0.

No Linux, um processo bem-sucedido retorna zero; caso contrário, retorna outro código.

In [1]: from subprocess import run

  In [2]: run(['test', '-e', 'arquivo_teste.txt']).returncode == 0
  Out[2]: True

  In [3]: run(['test', '-e', 'nao-existo.txt']).returncode == 0
  Out[3]: False
  

Nesse código, importamos o módulo “subprocess” e utilizamos a função run para obter o código de retorno do processo.

Verificando a existência de um arquivo com o módulo subprocess

In [4]: run(['test', '-f', 'arquivo_teste.txt']).returncode == 0
  Out[4]: True

  In [5]: run(['test', '-f', 'diretorio_teste']).returncode == 0
  Out[5]: False
  

Verificando a existência de um diretório com o módulo subprocess

In [6]: run(['test', '-d', 'arquivo_teste.txt']).returncode == 0
  Out[6]: False

  In [7]: run(['test', '-d', 'diretorio_teste']).returncode == 0
  Out[7]: True
  

Embora funcional, esta opção não é recomendada, pois consome mais recursos sem oferecer nenhuma vantagem significativa.

Conclusão

O Python é uma linguagem amplamente utilizada para automatizar processos interagindo com o sistema operacional. Uma tarefa comum é a verificação da existência de arquivos e diretórios.

As formas mais simples de realizar essa verificação são:

  • Abrir um arquivo e tratar as exceções de arquivo imediatamente.
  • Utilizar a função “exists()” dos módulos “os.path” ou “pathlib”.

Neste guia, você aprendeu:

  • Como abrir um arquivo e tratar exceções em caso de não existência.
  • O significado dos caminhos de arquivos.
  • Três funções diferentes do submódulo “os.path” para verificar a existência de arquivos e diretórios.
  • A diferença na utilização de barras (/) e barras invertidas (\) em sistemas Unix e Windows.

Leitura complementar: O que é um subprocesso em Python? [5 exemplos de uso]