Aplicações Python executadas no Windows frequentemente precisam descobrir quais unidades estão disponíveis antes de procurar arquivos, criar backups ou exibir opções ao usuário. O módulo os oferece os.listdrives(), uma função dedicada a retornar as raízes das unidades existentes no sistema.
Esse recurso evita soluções frágeis baseadas em testar letras de A a Z, interpretar comandos do terminal ou depender de bibliotecas externas. Neste guia, você aprenderá como usar os.listdrives(), validar caminhos, combinar o resultado com pathlib, lidar com unidades removíveis e de rede e construir rotinas seguras para automação no Windows.
O que os.listdrives retorna
A função retorna uma lista de strings com caminhos absolutos que representam as raízes das unidades disponíveis. Em um computador comum, o resultado pode incluir C:\, D:\ e outras letras associadas a discos internos, partições, pendrives, leitores ópticos ou unidades de rede mapeadas.
import os
for unidade in os.listdrives():
print(unidade)
A presença de uma unidade na lista não garante que todo acesso será bem-sucedido. Uma mídia removível pode ter sido ejetada, uma unidade de rede pode estar desconectada e permissões podem impedir a leitura.
Disponibilidade por plataforma
os.listdrives() é específico do Windows. Em código multiplataforma, verifique o sistema operacional antes de chamar a função. Isso evita erros em Linux e macOS.
import os
import sys
if sys.platform == "win32":
unidades = os.listdrives()
else:
unidades = ["/"]
Essa adaptação simples permite que uma aplicação trate raízes de arquivos de maneira coerente em diferentes sistemas, embora o conceito de unidade com letra seja próprio do Windows.
Convertendo para objetos Path
O módulo pathlib torna mais confortável combinar caminhos, consultar propriedades e percorrer diretórios. Converta cada resultado para Path quando precisar realizar operações adicionais.
from pathlib import Path
import os
unidades = [Path(caminho) for caminho in os.listdrives()]
for unidade in unidades:
print(unidade, unidade.exists())
Mesmo que listdrives() tenha retornado a raiz, uma nova verificação é útil porque o estado do dispositivo pode mudar entre a descoberta e o acesso.
Listando espaço disponível
Uma aplicação de backup normalmente precisa conhecer o espaço livre. Combine as unidades com shutil.disk_usage().
import os
import shutil
for unidade in os.listdrives():
try:
total, usado, livre = shutil.disk_usage(unidade)
except OSError as erro:
print(unidade, "indisponível:", erro)
continue
print(unidade, "livre:", livre // (1024 ** 3), "GB")
O tratamento de OSError é essencial, especialmente para dispositivos removíveis, leitores sem mídia e compartilhamentos de rede instáveis.
Unidades removíveis e mudanças de estado
Entre a chamada a os.listdrives() e uma operação posterior, o usuário pode remover um pendrive. Por isso, não mantenha o resultado em cache por tempo indefinido quando a aplicação depende de dispositivos externos. Atualize a lista ao abrir um seletor ou antes de iniciar uma operação importante.
Também evite assumir que a letra de uma unidade será sempre a mesma. O Windows pode atribuir outra letra em uma conexão futura.
Unidades de rede
Unidades de rede mapeadas podem aparecer junto com discos locais. Elas podem exigir autenticação, apresentar latência ou ficar indisponíveis temporariamente. Rotinas que percorrem todas as unidades devem usar timeouts quando interagem com serviços externos e permitir que o usuário exclua destinos lentos.
Para caminhos UNC, como \\servidor\compartilhamento, a origem pode não aparecer como uma letra mapeada. Portanto, listdrives() não substitui uma configuração explícita de compartilhamentos conhecidos.
Filtrando unidades acessíveis
from pathlib import Path
import os
def unidades_acessiveis():
resultado = []
for raiz in os.listdrives():
caminho = Path(raiz)
try:
next(caminho.iterdir(), None)
except (OSError, PermissionError):
continue
resultado.append(caminho)
return resultado
Esse teste verifica acesso básico, mas percorrer uma raiz pode ser custoso em algumas unidades. Use-o apenas quando realmente precisar confirmar leitura.
Procurando um arquivo em várias unidades
Uma aplicação pode procurar uma pasta conhecida em todas as raízes. Limite a profundidade da busca para evitar percorrer discos inteiros sem necessidade.
from pathlib import Path
import os
def procurar_na_raiz(nome):
encontrados = []
for raiz in os.listdrives():
candidato = Path(raiz) / nome
try:
if candidato.exists():
encontrados.append(candidato)
except OSError:
pass
return encontrados
Essa abordagem é adequada quando o caminho relativo é conhecido. Para buscas amplas, ofereça filtros e permita cancelamento.
Segurança ao receber caminhos do usuário
Não concatene textos sem validação. Resolva o caminho e confirme se ele permanece dentro da unidade autorizada. Isso é importante em ferramentas que recebem nomes de pasta por API ou interface web.
from pathlib import Path
def dentro_da_unidade(raiz, relativo):
base = Path(raiz).resolve()
destino = (base / relativo).resolve()
return destino == base or base in destino.parents
Em operações destrutivas, exija confirmação adicional e nunca permita que uma string vazia resulte na raiz inteira como alvo.
Construindo um seletor de unidade
Para uma interface de terminal, mostre a lista numerada e mantenha a associação entre o índice e o caminho original.
import os
unidades = os.listdrives()
for indice, unidade in enumerate(unidades, start=1):
print(f"{indice}. {unidade}")
Depois de receber a escolha, valide se o índice está no intervalo e atualize a lista antes de iniciar uma operação longa.
Tratamento de erros
As exceções mais comuns são OSError, PermissionError e FileNotFoundError. Registre qual unidade falhou, mas permita que o processamento continue nas demais quando isso for seguro. Em aplicações gráficas, apresente mensagens claras em vez de exibir apenas o código do erro do sistema.
Testes
Não faça testes dependerem das letras reais do computador. Encapsule a descoberta em uma função e simule seu retorno. Assim, você pode testar listas vazias, uma única unidade, unidades inacessíveis e mudanças entre duas chamadas.
def escolher_unidades(listar):
return [u for u in listar() if u]
Nos testes, passe uma função falsa que retorna valores controlados.
Quando não usar os.listdrives
Se o programa já recebe um diretório configurado, não é necessário examinar todas as unidades. Para localizar pastas conhecidas do usuário, prefira variáveis de ambiente e APIs apropriadas. Para servidores Linux, trabalhe com pontos de montagem e não tente reproduzir letras de unidade.
Conteúdos relacionados
Veja também os guias da Academify sobre módulo os, pathlib, arquivos grandes e tratamento de exceções. Consulte ainda a documentação oficial de os e a documentação de shutil.
Boas práticas
Atualize a lista antes de operações importantes, trate falhas por unidade, não confie em letras fixas, limite buscas e valide caminhos fornecidos externamente. Em aplicações multiplataforma, isole a lógica específica do Windows em uma função pequena e testável.
Conclusão
os.listdrives() oferece uma forma direta e padronizada de descobrir as unidades disponíveis no Windows. Com validação posterior, tratamento de erros e integração com pathlib e shutil, a função ajuda a construir seletores de armazenamento, ferramentas de backup e automações mais confiáveis. O ponto principal é tratar a lista como uma fotografia momentânea: dispositivos e redes podem mudar, permissões podem falhar e cada acesso deve ser verificado com segurança.







