HOWTO · Python
Abra todos os arquivos em um diretório em Python
Ler arquivos em um diretório com os.listdir(), selecionar correspondências com glob.glob(), examinar entradas com os.scandir() ou incluir diretórios aninhados com os.walk().
Nesta página
Para ler arquivos de texto em um diretório, use os.listdir() para um único diretório, glob.glob() para selecionar nomes por um padrão, os.scandir() para inspecionar entradas ou os.walk() para incluir diretórios aninhados. Construa os caminhos com os nomes retornados e use open() em uma instrução with. Estes exemplos leem texto; arquivos binários precisam do modo binário, como "rb", ou de um analisador específico do formato.
Abrir arquivos em um diretório com os.walk()
Use os.walk() quando os arquivos podem estar no diretório inicial ou em qualquer diretório abaixo dele. Em cada iteração, ela produz três valores: o caminho do diretório atual (root), os nomes de seus diretórios filhos (dirnames) e os nomes dos arquivos diretamente naquele diretório (filenames). Combine root e cada nome de arquivo para obter um caminho; combinar apenas o diretório inicial e o nome do arquivo deixaria de fora os arquivos em diretórios aninhados.
Este exemplo cria uma pequena árvore de diretórios para que possa ser executado como está escrito. Ordenar os nomes de diretórios e arquivos torna a ordem de processamento previsível para esta configuração; caso contrário, a ordem de travessia dos diretórios não é garantida.
Execute este exemplo:
import os
import tempfile
with tempfile.TemporaryDirectory() as directory:
nested = os.path.join(directory, "notes")
os.mkdir(nested)
for folder, name, contents in [
(directory, "summary.txt", "Ready"),
(nested, "details.txt", "More notes"),
]:
with open(os.path.join(folder, name), "w", encoding="utf-8") as file:
file.write(contents)
for root, dirnames, filenames in os.walk(directory):
dirnames.sort()
for filename in sorted(filenames):
path = os.path.join(root, filename)
with open(path, encoding="utf-8") as file:
print(f"{filename}: {file.read()}")
os.walk() pode atravessar de cima para baixo ou de baixo para cima. O padrão é de cima para baixo, o que é adequado quando os arquivos são processados à medida que são encontrados. O exemplo usa explicitamente UTF-8; escolha uma codificação que corresponda aos seus arquivos de texto. Se os arquivos usarem codificações diferentes, trate-os de acordo com o formato, em vez de supor que uma única codificação funcione para todos. Para diretórios que o seu processo não pode ler, trate os erros de sistema de arquivos resultantes de acordo com as necessidades da sua aplicação.
Abrir arquivos em um diretório com os.listdir()
os.listdir() retorna os nomes das entradas diretamente dentro de um diretório. Ela não desce para os diretórios filhos, e seu resultado pode incluir tanto arquivos quanto diretórios. Combine cada nome com o caminho do diretório e verifique os.path.isfile() antes de abri-lo, como mostrado abaixo.
import os
import tempfile
with tempfile.TemporaryDirectory() as directory:
with open(os.path.join(directory, "one.txt"), "w", encoding="utf-8") as file:
file.write("First file")
os.mkdir(os.path.join(directory, "archive"))
for name in sorted(os.listdir(directory)):
path = os.path.join(directory, name)
if os.path.isfile(path):
with open(path, encoding="utf-8") as file:
print(f"{name}: {file.read()}")
Esta abordagem é útil quando você quer cada arquivo regular em um diretório e não precisa de correspondência por padrão. A verificação os.path.isfile() segue links simbólicos para arquivos; se a sua aplicação precisar distinguir links ou aplicar uma política diferente, use as verificações apropriadas de caminho ou de entrada de diretório. Mantenha o bloco with ao redor de cada arquivo para que o Python o feche após a leitura, inclusive se o processamento posterior sair desse bloco mais cedo.
Abrir arquivos correspondentes com glob.glob()
glob.glob() seleciona caminhos usando um padrão de nome de arquivo. Um padrão como *.txt corresponde a arquivos de texto diretamente no diretório nomeado; por si só, ele não pesquisa nos diretórios filhos. Os caminhos retornados podem ser passados diretamente para open(). Use os.walk() quando a tarefa for visitar uma árvore inteira, ou construa deliberadamente um padrão recursivo, se for isso que você precisa.
import glob
import os
import tempfile
with tempfile.TemporaryDirectory() as directory:
for name, contents in [("readme.txt", "Instructions"), ("data.csv", "id")]:
with open(os.path.join(directory, name), "w", encoding="utf-8") as file:
file.write(contents)
pattern = os.path.join(directory, "*.txt")
for path in sorted(glob.glob(pattern)):
with open(path, encoding="utf-8") as file:
print(f"{os.path.basename(path)}: {file.read()}")
Altere o componente final do padrão para selecionar um conjunto diferente de nomes de arquivo, como report-*.csv. Ordenar as correspondências é útil quando o trabalho posterior depende de uma ordem estável. Um padrão também pode corresponder a nomes de diretórios, portanto filtre os caminhos correspondentes com os.path.isfile() se o padrão não for limitado a arquivos.
Abrir arquivos em um diretório com os.scandir()
os.scandir() produz objetos de entrada de diretório que expõem o nome e o caminho de cada entrada e fornecem métodos como is_file(). Ela é útil quando o loop precisa verificar uma entrada antes de abri-la ou inspecionar informações da entrada. O iterador é um gerenciador de contexto, portanto use with para fechá-lo quando a iteração terminar. Este exemplo verifica entradas e lê arquivos regulares; ele não recorre aos diretórios filhos.
import os
import tempfile
with tempfile.TemporaryDirectory() as directory:
with open(os.path.join(directory, "notes.txt"), "w", encoding="utf-8") as file:
file.write("Scanned text")
os.mkdir(os.path.join(directory, "archive"))
with os.scandir(directory) as entries:
for entry in sorted(entries, key=lambda item: item.name):
if entry.is_file():
with open(entry.path, encoding="utf-8") as file:
print(f"{entry.name}: {file.read()}")
entry.name é o nome dentro do diretório escaneado, enquanto entry.path é o caminho a ser usado ao abrir essa entrada. Assim como os.listdir(), uma única chamada a os.scandir() abrange apenas um diretório. Se as entradas puderem mudar entre a verificação e a abertura, o estado do sistema de arquivos pode mudar durante esse intervalo, portanto o código que lida com diretórios não confiáveis ou modificados simultaneamente também deve levar em conta erros no momento da abertura.
Escolher o método certo para o seu diretório
Escolha os.listdir() para uma passagem direta e não recursiva sobre um diretório. Escolha glob.glob() quando um padrão de nome de arquivo deve decidir quais caminhos processar. Escolha os.walk() quando arquivos em diretórios aninhados fizerem parte da tarefa. Escolha os.scandir() quando cada entrada precisar de uma verificação de arquivo ou de outras informações da entrada antes de você agir sobre ela.
Todos os quatro métodos enumeram o conteúdo dos diretórios, mas a ordem de enumeração não é garantida; ordene nomes ou caminhos quando o processamento repetível importar. Os exemplos usam objetos de arquivo gerenciados por contexto e o modo de texto UTF-8. Adapte a codificação aos arquivos de origem e use o modo binário ou um analisador quando os arquivos não forem texto simples. Permissões de acesso, arquivos que desaparecem durante o processamento e diferenças de codificação específicas da aplicação podem exigir tratamento adicional no código de produção.