O autor selecionou a COVID-19 Relief Fund para receber uma doação como parte do programa Write for DOnations.
O Python 3 inclui o módulo pathlib
para manipular caminhos de sistema de arquivos de maneira independente, seja qual for o sistema operacional. O pathlib
é semelhante ao módulo os.path
, mas o pathlib
oferece um nível mais elevado — e muitas vezes mais conveniente — de interface do que o os.path
.
Podemos identificar arquivos em um computador com caminhos hierárquicos. Por exemplo, podemos identificar o arquivo wave.txt
em um computador com este caminho: /Users/sammy/ocean/wave.txt
. Os sistemas operacionais representam caminhos de maneira ligeiramente diferente. O Windows pode representar o caminho para o arquivo wave.txt
como C:\Users\sammy\ocean\wave.txt
.
O módulo pathlib
pode ser útil para você se em seu programa Python você estiver criando ou movendo arquivos no sistema de arquivos, listando arquivos no sistema de arquivos em que todos correspondam a uma dada extensão ou padrão, ou criando caminhos de arquivo apropriados ao sistema operacional baseados em coleções de strings brutas. Embora seja possível usar outras ferramentas (como o módulo os.path
) para realizar muitas dessas tarefas, o módulo pathlib
permite que você execute essas operações com um alto grau de legibilidade e uma quantidade mínima de código.
Neste tutorial, vamos revisar algumas das maneiras de usar o módulo pathlib
para representar e manipular os caminhos de sistema de arquivos.
Para tirar o máximo proveito deste tutorial, é recomendado ter alguma familiaridade com programação em Python 3. Você pode revisar esses tutoriais para as informações básicas necessárias:
Path
O módulo pathlib
oferece várias classes, mas uma das mais importantes é a classe Path
. As instâncias da classe Path
representam um caminho para um arquivo ou diretório no sistema de arquivos do nosso computador.
Por exemplo, o código a seguir cria uma instância Path
que representa parte do caminho para um arquivo wave.txt
:
from pathlib import Path
wave = Path("ocean", "wave.txt")
print(wave)
Se executarmos esse código, receberemos um resultado como o seguinte:
Outputocean/wave.txt
from pathlib import Path
torna a classe Path
disponível para nosso programa. Em seguida, Path("ocean", "wave.txt")
cria uma nova instância do Path
. Imprimir o resultado mostra que o Python adicionou o separador de sistema operacional /
apropriado entre os dois componentes do caminho que demos a ele: "ocean"
e "wave.txt"
.
Nota: dependendo do seu sistema operacional, o resultado pode variar ligeiramente dos resultados de exemplo exibidos neste tutorial. Se estiver utilizando o Windows, por exemplo, seu resultado para este primeiro exemplo se pareceria com ocean\wave.txt
.
Agora, o objeto Path
atribuído à variável wave
contém um caminho relativo. Em outras palavras, ocean/wave.txt
pode existir em vários lugares em nosso sistema de arquivos. Para exemplificar, ele pode existir em /Users/user_1/ocean/wave.txt
ou /Users/user_2/research/ocean/wave.txt
, mas não especificamos exatamente a qual deles estamos nos referindo. Um caminho absoluto, por outro lado, refere-se sem sombra de dúvidas a uma localização específica no sistema de arquivos.
Use o Path.home()
para obter o caminho absoluto para o diretório home do usuário atual:
home = Path.home()
wave_absolute = Path(home, "ocean", "wave.txt")
print(home)
print(wave_absolute)
Se executarmos esse código, receberemos um resultado parecido com o seguinte:
Output/Users/sammy
/Users/sammy/ocean/wave.txt
Nota: como mencionado anteriormente, seu resultado irá variar dependendo do seu sistema operacional. Seu diretório home, por consequência, também será diferente de /Users/sammy
.
Path.home()
retorna uma instância Path
com um caminho absoluto para o diretório home do usuário atual. Em seguida, passamos essa instância Path
e as strings "ocean"
e "wave.txt"
para outro construtor Path
de forma a criar um caminho absoluto para o arquivo wave.txt
. O resultado mostra que a primeira linha é o diretório home, e a segunda linha é o diretório home mais ocean/wave.txt
.
Este exemplo também ilustra uma característica importante da classe Path
: o construtor Path
aceita tanto strings quanto objetos Path
pré-existentes.
Vamos analisar as strings e objetos Path
no construtor Path
um pouco mais de perto:
shark = Path(Path.home(), "ocean", "animals", Path("fish", "shark.txt"))
print(shark)
Se executarmos esse código Python, receberemos um resultado semelhante ao seguinte:
Output/Users/sammy/ocean/animals/fish/shark.txt
shark
é um Path
para um arquivo que construímos usando dois objetos Path
(Path.home()
e Path("fish", "shark.txt")
) e as strings ("ocean"
e "animals"
). O construtor Path
lida com os dois tipos de objetos de maneira inteligente e une-os corretamente usando o separador de sistema operacional adequado, neste caso, /
.
Agora que aprendemos como construir instâncias Path
, vamos analisar como você pode usar essas instâncias para acessar informações sobre um arquivo.
Podemos usar os atributos name
e suffix
para acessar os nomes e sufixos dos arquivos:
wave = Path("ocean", "wave.txt")
print(wave)
print(wave.name)
print(wave.suffix)
Ao executar este código, receberemos um resultado semelhante ao seguinte:
Output/Users/sammy/ocean/wave.txt
wave.txt
.txt
Este resultado mostra que o nome do arquivo no final do nosso caminho é wave.txt
e o sufixo desse arquivo é .txt
.
As instâncias Path
também oferecem a função with_name
que permite criar rapidamente um novo objeto Path
com um nome diferente:
wave = Path("ocean", "wave.txt")
tides = wave.with_name("tides.txt")
print(wave)
print(tides)
Se executarmos o código acima, receberemos um resultado como o seguinte:
ocean/wave.txt
ocean/tides.txt
Primeiro, o código constrói uma instância Path
que aponta para um arquivo chamado wave.txt
. Em seguida, chamamos o método with_name
em wave
para retornar uma segunda instância Path
que aponta para um novo arquivo chamado tides.txt
. A porção de diretório ocean/
do caminho permanece inalterada, deixando o caminho final como sendo ocean/tides.txt
Às vezes, é útil acessar diretórios que contêm um dado caminho. Vamos considerar um exemplo:
shark = Path("ocean", "animals", "fish", "shark.txt")
print(shark)
print(shark.parent)
Se executarmos esse código, receberemos um resultado parecido com o seguinte:
Outputocean/animals/fish/shark.txt
ocean/animals/fish
O atributo parent
em uma instância Path
retorna o ancestral mais próximo de um determinado caminho de arquivo. Neste caso, ele retorna o diretório que contém o arquivo shark.txt
: ocean/animals/fish
.
Podemos acessar o atributo parent
várias vezes seguidas para percorrer a árvore de ancestralidade de um dado arquivo:
shark = Path("ocean", "animals", "fish", "shark.txt")
print(shark)
print(shark.parent.parent)
Se executarmos esse código, receberemos o seguinte resultado:
Outputocean/animals/fish/shark.txt
ocean/animals
O resultado é semelhante ao resultado anterior, mas agora percorremos mais um nível acessando .parent
uma segunda vez. Dois diretórios acima de shark.txt
, você encontrará o diretório ocean/animals
.
Também é possível usar a classe Path
para listar arquivos usando o método glob
.
Suponha que tivéssemos uma estrutura de diretório que se parecia com esta:
└── ocean
├── animals
│ └── fish
│ └── shark.txt
├── tides.txt
└── wave.txt
Um diretório ocean
contém os arquivos tides.txt
e wave.txt
. Temos um arquivo chamado shark.txt
contido no diretório ocean
, um diretório animals
e um diretório fish
: ocean/animals/fish
.
Para listar todos os arquivos .txt
no diretório ocean
, podemos utilizar:
for txt_path in Path("ocean").glob("*.txt"):
print(txt_path)
Esse código produziria um resultado como este:
Outputocean/wave.txt
ocean/tides.txt
O padrão glob "*.txt"
encontra todos os arquivos terminados em .txt
. Como a amostra de código executa esse glob no diretório ocean
, ela retorna os dois arquivos .txt
no diretório ocean
: wave.txt
e tides.txt
.
Nota: se você quiser replicar os resultados mostrados neste exemplo, você precisará imitar a estrutura de diretórios aqui ilustrada em seu computador.
Também podemos usar o método glob
recursivamente. Para listar todos os arquivos .txt
no diretório ocean
e todos os seus subdiretórios, podemos utilizar:
for txt_path in Path("ocean").glob("**/*.txt"):
print(txt_path)
Se executarmos esse código, receberemos um resultado como o seguinte:
Outputocean/wave.txt
ocean/tides.txt
ocean/animals/fish/shark.txt
A parte **
do padrão glob irá corresponder a esse diretório e todos os diretórios abaixo dele, recursivamente. Dessa forma, não só temos os arquivos wave.txt
e tides.txt
no resultado, mas também recebemos o arquivo shark.txt
que estava contido em ocean/animals/fish
.
Podemos usar o método Path.relative_to
para computar caminhos em relação uns aos outros. O método relative_to
é útil quando, por exemplo, você quiser recuperar parte de um caminho de arquivo longo.
Considere o código a seguir:
shark = Path("ocean", "animals", "fish", "shark.txt")
below_ocean = shark.relative_to(Path("ocean"))
below_animals = shark.relative_to(Path("ocean", "animals"))
print(shark)
print(below_ocean)
print(below_animals)
Se executarmos o código acima, receberemos um resultado como o seguinte:
Outputocean/animals/fish/shark.txt
animals/fish/shark.txt
fish/shark.txt
O método relative_to
retorna um novo objeto Path
relativo ao argumento dado. Em nosso exemplo, computamos o Path
para o shark.txt
relativo ao diretório ocean
, e então relativo tanto ao diretório ocean
quanto ao diretório animals
.
Se relative_to
não puder computar uma resposta porque lhe fornecemos um caminho não relacionado, ele gera um ValueError
:
shark = Path("ocean", "animals", "fish", "shark.txt")
shark.relative_to(Path("unrelated", "path"))
Receberemos uma exceção ValueError
gerada a partir deste código que será algo parecido com isto:
OutputTraceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/lib/Python3.8/pathlib.py", line 899, in relative_to
raise ValueError("{!r} does not start with {!r}"
ValueError: 'ocean/animals/fish/shark.txt' does not start with 'unrelated/path'
unrelated/path
não faz parte de ocean/animals/fish/shark.txt
, então não existe nenhuma maneira para o Python computar um caminho relativo.
O módulo pathlib
é uma parte poderosa da Biblioteca Padrão do Python que nos permite manipular caminhos do sistema de arquivos rapidamente em qualquer sistema operacional. Neste tutorial, aprendemos a usar alguns utilitários chave do pathlib
para acessar atributos de arquivo, listar arquivos com padrões glob e percorrer arquivos e diretórios pais.
O módulo pathlib
também oferece classes e utilitários adicionais que não abordamos neste tutorial. Agora que você tem um conhecimento base, use a documentação do módulo pathlib
para aprender mais sobre outras classes e utilitários disponíveis.
Se estiver interessado em usar outras bibliotecas do Python, confira os seguintes tutoriais:
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
This textbox defaults to using Markdown to format your answer.
You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!