Introdução
Neste laboratório, você aprenderá a manipular caminhos de arquivos e diretórios em Python usando o módulo moderno pathlib. Embora o módulo mais antigo os.path ainda seja comum, o pathlib oferece uma abordagem orientada a objetos que torna a manipulação de caminhos mais intuitiva e legível. Você aprenderá a criar, inspecionar, validar e manipular caminhos, arquivos e diretórios de uma maneira que funciona em diferentes sistemas operacionais como Windows, macOS e Linux.
Ao final deste laboratório, você estará proficiente em:
- Juntar componentes de caminho corretamente.
- Criar e gerenciar diretórios.
- Diferenciar entre caminhos absolutos e relativos.
- Validar a existência e o tipo de caminhos.
- Realizar operações comuns de arquivo, como copiar, mover e excluir.
- Percorrer árvores de diretórios para encontrar arquivos e pastas.
Operações Básicas de Caminho
Nesta etapa, você aprenderá os fundamentos da manipulação de caminhos usando o módulo pathlib. Isso inclui juntar componentes de caminho, obter o diretório de trabalho atual e criar novos diretórios.
O módulo pathlib fornece uma maneira elegante e multiplataforma de lidar com caminhos do sistema de arquivos. No Windows, os caminhos usam barras invertidas (\), enquanto em sistemas do tipo Unix (Linux, macOS), eles usam barras normais (/). Usar pathlib garante que seu código funcione em qualquer plataforma sem ajustes manuais.
Nota: Se você não está familiarizado com o uso do WebIDE (semelhante ao VS Code), aprenda primeiro neste laboratório.
Primeiro, vamos ver como juntar componentes de caminho. O operador / é um atalho intuitivo para joinpath().
- Abra o arquivo
main.pyno explorador de arquivos à esquerda. - Substitua o conteúdo de
main.pypelo seguinte código para juntar componentes de caminho e imprimir o resultado.
from pathlib import Path
## Join path components using the / operator
my_path = Path('usr') / 'bin' / 'spam'
print(my_path)
- Execute o script no terminal:
python3 main.py
Você verá a seguinte saída, que demonstra como o pathlib forma corretamente um caminho no estilo Unix:
usr/bin/spam
Em seguida, vamos obter o diretório de trabalho atual usando Path.cwd().
- Substitua o conteúdo de
main.pypelo seguinte código (isso substitui o código anterior):
from pathlib import Path
## Get the current working directory
cwd = Path.cwd()
print(cwd)
- Execute o script novamente:
python3 main.py
A saída mostrará o diretório de trabalho atual, que é /home/labex/project neste ambiente:
/home/labex/project
Finalmente, vamos criar um novo diretório. Um FileNotFoundError ocorre se você tentar criar um diretório onde o diretório pai não existe. Para evitar isso, use mkdir(parents=True), que cria todos os diretórios pais necessários.
- Substitua o conteúdo de
main.pypelo seguinte código para criar uma estrutura de diretórios aninhada:
from pathlib import Path
## Get the current working directory
cwd = Path.cwd()
## Define the path for the new nested directories
new_dirs = cwd / 'delicious' / 'walnut' / 'waffles'
## Create the directories, including any missing parents
new_dirs.mkdir(parents=True, exist_ok=True)
print(f"Successfully created: {new_dirs}")
O argumento
exist_ok=Trueevita um erro se o diretório já existir. Isso significa que você pode executar o script várias vezes sem erros.
- Execute o script:
python3 main.py
O script criará os diretórios aninhados e imprimirá uma mensagem de confirmação:
Successfully created: /home/labex/project/delicious/walnut/waffles
Você pode verificar a criação do diretório executando ls -R delicious no terminal.
Caminhos Absolutos vs. Relativos
Nesta etapa, você aprenderá a distinguir e trabalhar com caminhos absolutos e relativos.
- Um caminho absoluto começa a partir da raiz do sistema de arquivos (por exemplo,
/no Linux ouC:\no Windows). - Um caminho relativo é definido a partir do diretório de trabalho atual.
O pathlib fornece métodos para verificar se um caminho é absoluto, resolver um caminho para sua forma absoluta e encontrar um caminho relativo a partir de um ponto de partida.
Primeiro, vamos verificar se um caminho é absoluto usando is_absolute().
- Substitua o conteúdo de
main.pypelo seguinte código:
from pathlib import Path
## Check if paths are absolute
print(f"Path('/') is absolute: {Path('/').is_absolute()}")
print(f"Path('..') is absolute: {Path('..').is_absolute()}")
- Execute o script:
python3 main.py
A saída confirma que / é um caminho absoluto, enquanto .. (diretório pai) é relativo.
Path('/') is absolute: True
Path('..') is absolute: False
Em seguida, você pode obter o caminho absoluto completo de um caminho relativo usando resolve(). Isso é útil para converter caminhos relativos como . (diretório atual) ou .. (diretório pai) em sua forma completa e inequívoca.
- Substitua o conteúdo de
main.pypelo seguinte código:
from pathlib import Path
## Resolve a relative path to its absolute form
## '..' refers to the parent directory of the current working directory
resolved_path = Path('..').resolve()
print(f"Current working directory: {Path.cwd()}")
print(f"Resolved path of '..': {resolved_path}")
- Execute o script:
python3 main.py
A saída mostrará o diretório atual e o caminho absoluto resolvido de seu pai.
Current working directory: /home/labex/project
Resolved path of '..': /home/labex
Finalmente, você pode calcular um caminho relativo de um caminho para outro usando relative_to().
- Substitua o conteúdo de
main.pypelo seguinte código para calcular um caminho relativo:
from pathlib import Path
## Get a relative path from a starting point
## This shows the path to 'passwd' relative to the root directory '/'
relative_path = Path('/etc/passwd').relative_to('/')
print(f"Path to '/etc/passwd' relative to '/': {relative_path}")
- Execute o script:
python3 main.py
A saída mostra o caminho relativo ao diretório raiz:
Path to '/etc/passwd' relative to '/': etc/passwd
Validação e Inspeção de Caminhos
Nesta etapa, você aprenderá como verificar as propriedades de um caminho, como se ele existe e se é um arquivo ou um diretório. Você também aprenderá a recuperar metadados de arquivos, como seu tamanho.
Uma tarefa comum é verificar se um arquivo ou diretório existe antes de tentar acessá-lo. O método exists() é perfeito para isso.
- Abra
main.pye substitua seu conteúdo pelo seguinte código. Isso verificará a existência do diretório atual (.), de um arquivo (setup.py) e de um arquivo inexistente.
from pathlib import Path
## Check if paths exist
print(f"Path('.') exists: {Path('.').exists()}")
print(f"Path('setup.py') exists: {Path('setup.py').exists()}")
print(f"Path('nonexistentfile') exists: {Path('nonexistentfile').exists()}")
- Execute o script:
python3 main.py
A saída confirmará quais caminhos existem:
Path('.') exists: True
Path('setup.py') exists: True
Path('nonexistentfile') exists: False
Você também pode ser mais específico e verificar se um caminho aponta para um arquivo com is_file() ou para um diretório com is_dir().
- Substitua o conteúdo de
main.pypelo seguinte código para realizar essas verificações:
from pathlib import Path
## Check if a path is a file
print(f"Path('setup.py').is_file(): {Path('setup.py').is_file()}")
print(f"Path('/home').is_file(): {Path('/home').is_file()}")
## Check if a path is a directory
print(f"Path('/').is_dir(): {Path('/').is_dir()}")
print(f"Path('setup.py').is_dir(): {Path('setup.py').is_dir()}")
- Execute o script:
python3 main.py
A saída identificará corretamente o tipo de cada caminho:
Path('setup.py').is_file(): True
Path('/home').is_file(): False
Path('/').is_dir(): True
Path('setup.py').is_dir(): False
Finalmente, para obter informações detalhadas do arquivo, como seu tamanho, você pode usar o método stat(). Ele retorna um objeto com vários atributos, incluindo st_size para o tamanho do arquivo em bytes.
- Substitua o conteúdo de
main.pypelo seguinte código para obter o tamanho de um arquivo do sistema:
from pathlib import Path
import os
## Define the path to a file
file_path = Path('/bin/python3')
## Get file statistics
stat_info = file_path.stat()
## Print the size in bytes
print(f"File: {file_path}")
print(f"Size: {stat_info.st_size} bytes")
- Execute o script:
python3 main.py
A saída exibirá o tamanho do executável Python em bytes. O tamanho exato pode variar.
File: /bin/python3
Size: 10024 bytes
Gerenciamento de Arquivos e Pastas
Nesta etapa, você aprenderá a realizar operações comuns do sistema de arquivos, como copiar, mover, renomear e excluir arquivos e pastas, usando o módulo shutil em combinação com pathlib.
O módulo shutil fornece funções de alto nível para operações de arquivo. Vamos começar com a cópia de arquivos. shutil.copy() copia um único arquivo para um novo local.
- Abra o arquivo
manage_files.pyno explorador de arquivos à esquerda. - Substitua o conteúdo de
manage_files.pypelo código a seguir. Isso copiaráspam.txtpara o diretório/tmp/delicious.
import shutil
from pathlib import Path
## Define a origem e o destino
source_file = Path('/tmp/spam.txt')
destination_dir = Path('/tmp/delicious')
## Copia o arquivo
shutil.copy(source_file, destination_dir)
print(f"Copied '{source_file}' to '{destination_dir}'")
## Você também pode renomear o arquivo durante a cópia
shutil.copy('/tmp/eggs.txt', '/tmp/delicious/eggs2.txt')
print("Copied and renamed 'eggs.txt' to 'eggs2.txt'")
- Execute o script:
python3 manage_files.py
Para copiar uma árvore de diretórios inteira, use shutil.copytree().
- Adicione as seguintes linhas ao final de
manage_files.py(anexe estas linhas após o código existente):
## Copia uma árvore de diretórios inteira
shutil.copytree('/tmp/bacon', '/tmp/bacon_backup')
print("Copied directory '/tmp/bacon' to '/tmp/bacon_backup'")
Nota: Se você executar este script várias vezes,
shutil.copytree()falhará porque o diretório de destino já existe. Este é o comportamento esperado. Por enquanto, execute-o apenas uma vez.
- Execute o script novamente para ver em ação.
Em seguida, vamos mover e renomear arquivos com shutil.move(). Esta função pode mover um arquivo para um diretório diferente ou renomeá-lo.
- Substitua o conteúdo inteiro de
manage_files.pypelo código a seguir para moverbacon.txt:
import shutil
from pathlib import Path
## Cria o diretório de destino se ele não existir
Path('/tmp/eggs').mkdir(parents=True, exist_ok=True)
## Move um arquivo para um diretório (somente se a origem existir)
bacon_source = Path('/tmp/bacon.txt')
if bacon_source.exists():
shutil.move('/tmp/bacon.txt', '/tmp/eggs')
print("Moved '/tmp/bacon.txt' to '/tmp/eggs'")
else:
print("'/tmp/bacon.txt' not found (may have been moved already)")
## Move e renomeia um arquivo
## Primeiro, vamos recriar o arquivo para mover
Path('/tmp/bacon.txt').touch()
shutil.move('/tmp/bacon.txt', '/tmp/eggs/new_bacon.txt')
print("Moved and renamed '/tmp/bacon.txt' to '/tmp/eggs/new_bacon.txt'")
Nota: O código verifica se o arquivo de origem existe antes de movê-lo, para que você possa executar este script várias vezes com segurança. A segunda parte sempre criará um novo arquivo e o moverá.
- Execute o script.
Finalmente, vamos ver a exclusão de arquivos e pastas.
Path.unlink()exclui um único arquivo.Path.rmdir()exclui um diretório vazio.shutil.rmtree()exclui um diretório e todo o seu conteúdo.
- Substitua o conteúdo inteiro de
manage_files.pypelo seguinte:
from pathlib import Path
import shutil
## Cria um arquivo para excluir
file_to_delete = Path('/tmp/deleteme.txt')
file_to_delete.touch()
print(f"Created '{file_to_delete}'")
## Exclui o arquivo
file_to_delete.unlink()
print(f"Deleted '{file_to_delete}'")
## Cria um diretório para excluir
dir_to_delete = Path('/tmp/temp_dir')
dir_to_delete.mkdir(exist_ok=True)
## rmdir() só funciona em diretórios vazios
dir_to_delete.rmdir()
print(f"Deleted empty directory '{dir_to_delete}'")
## Usa shutil.rmtree() para excluir um diretório e seu conteúdo
## Nota: Isso falhará se o diretório não existir, o que é aceitável para este exemplo
if Path('/tmp/bacon_backup').exists():
shutil.rmtree('/tmp/bacon_backup')
print("Deleted directory '/tmp/bacon_backup' and all its contents")
else:
print("Directory '/tmp/bacon_backup' does not exist (may have been deleted already)")
Nota: Se você executar este script várias vezes, algumas operações podem falhar porque arquivos ou diretórios já foram excluídos. Isso é normal e demonstra que essas operações não são idempotentes (não podem ser repetidas com segurança).
- Execute o script para realizar as operações de exclusão.
Travessia de Diretórios
Nesta etapa, você aprenderá como listar o conteúdo de um diretório e percorrer recursivamente uma árvore de diretórios.
Para listar o conteúdo de um diretório, você pode usar o método iterdir(), que retorna um iterador de todos os itens (arquivos e diretórios) no caminho especificado.
- Primeiro, vamos configurar uma estrutura de diretório de exemplo. Execute este comando no terminal:
mkdir -p ~/project/data/level1 && touch ~/project/data/file0.txt ~/project/data/level1/file1.txt
- Agora, abra
main.pye substitua seu conteúdo pelo código a seguir para listar o conteúdo do diretório/usr/bin.
from pathlib import Path
## Listar conteúdo de um diretório
print("Conteúdo de '/usr/bin':")
count = 0
for f in Path('/usr/bin').iterdir():
if count < 5: ## Imprime os 5 primeiros itens para manter a saída curta
print(f)
count += 1
else:
break
- Execute o script:
python3 main.py
A saída mostrará os primeiros arquivos e diretórios dentro de /usr/bin. A lista exata pode variar.
Contents of '/usr/bin':
/usr/bin/[
/usr/bin/addpart
/usr/bin/apt
/usr/bin/apt-cache
/usr/bin/apt-cdrom
Você pode combinar iterdir() com stat() para calcular o tamanho total de todos os arquivos em um diretório.
- Substitua o conteúdo de
main.pypelo código a seguir. Observe que este código soma apenas os tamanhos dos filhos diretos e não recursa para subdiretórios.
from pathlib import Path
total_size = 0
directory = Path('/usr/bin')
for sub_path in directory.iterdir():
if sub_path.is_file(): ## Garante que apenas o tamanho dos arquivos seja adicionado
total_size += sub_path.stat().st_size
print(f"Tamanho total dos arquivos em '{directory}': {total_size} bytes")
- Execute o script. Ele imprimirá o tamanho total de todos os arquivos diretamente dentro de
/usr/bin.
Para tarefas mais complexas, você pode precisar "percorrer" (walk) uma árvore de diretórios inteira, visitando todos os subdiretórios e arquivos. O método rglob() é perfeito para isso. Ele encontra recursivamente todos os caminhos que correspondem a um padrão específico. Usar * como padrão corresponde a tudo.
- Primeiro, crie uma estrutura de diretório mais complexa para este exemplo. Execute isto no terminal:
mkdir -p /tmp/delicious/cats /tmp/delicious/walnut/waffles
touch /tmp/delicious/spam.txt /tmp/delicious/cats/catnames.txt /tmp/delicious/walnut/waffles/butter.txt
Nota: Você pode executar esses comandos várias vezes com segurança. O comando
mkdir -pnão falhará se os diretórios já existirem, etouchatualizará os carimbos de data/hora dos arquivos se eles já existirem.
- Substitua o conteúdo de
main.pypelo código a seguir para percorrer o diretório/tmp/delicious:
from pathlib import Path
p = Path('/tmp/delicious')
print(f"Percorrendo a árvore de diretórios para: {p}")
for i in p.rglob('*'):
print(i)
- Execute o script:
python3 main.py
A saída listará todos os arquivos e pastas dentro de /tmp/delicious e seus subdiretórios, demonstrando como rglob() percorre toda a árvore.
Walking directory tree for: /tmp/delicious
/tmp/delicious/spam.txt
/tmp/delicious/eggs2.txt
/tmp/delicious/cats
/tmp/delicious/walnut
/tmp/delicious/cats/catnames.txt
/tmp/delicious/walnut/waffles
/tmp/delicious/walnut/waffles/butter.txt
Resumo
Parabéns por completar o laboratório! Você aprendeu a gerenciar caminhos de arquivos e diretórios de forma eficaz em Python usando o módulo moderno pathlib.
Ao longo deste laboratório, você praticou:
- Criar e juntar caminhos de maneira multiplataforma usando objetos
Pathe o operador/. - Obter o diretório de trabalho atual e criar diretórios aninhados com
mkdir(parents=True). - Diferenciar entre caminhos absolutos e relativos e converter entre eles usando
is_absolute(),resolve()erelative_to(). - Validar caminhos com
exists(),is_file()eis_dir(), e inspecionar metadados de arquivos comstat(). - Realizar tarefas essenciais de gerenciamento de arquivos, como copiar, mover e excluir, com o módulo
shutile métodos dopathlib. - Percorrer estruturas de diretórios para listar conteúdos com
iterdir()e encontrar itens recursivamente comrglob().
Essas habilidades são fundamentais para escrever aplicações Python robustas e de fácil manutenção que interagem com o sistema de arquivos.



