Python pathlib
Nas aulas anteriores, a Ana abriu, leu e gravou arquivos com open(). Mas os arquivos de verdade não ficam soltos: ficam dentro de pastas, que ficam dentro de outras pastas. A lojinha da Ana já tem uma pasta loja, com a lista de produtos, a lista de clientes e uma pasta só para as vendas de cada mês. Para o programa saber onde cada arquivo está, criar pastas novas, conferir se um arquivo existe antes de abrir e listar o que há dentro de uma pasta, o Python tem o módulo pathlib (de path, "caminho", e lib, de library, "biblioteca").
- O que é um caminho e como criar um com
Path. - A juntar pedaços de caminho com a barra
/, sem se preocupar com o sistema. - A pegar as partes de um caminho:
name,stem,suffix,parent. - A perguntar se um arquivo ou pasta existe:
exists(),is_file(),is_dir(). - A criar pastas com
mkdir(), e as opçõesparentseexist_ok. - A ler e gravar um arquivo inteiro numa linha:
read_text()ewrite_text(). - A listar uma pasta com
iterdir()e procurar arquivos comglob()erglob(). - Os erros reais:
FileNotFoundError,FileExistsError,IsADirectoryError, a barra entre dois textos e a pasta que não está vazia.
A ideia: o endereço de um arquivo
Para mandar uma carta para a Ana, você escreve o endereço do mais geral para o mais específico: cidade, bairro, rua, número. O computador faz igual com os arquivos. O arquivo janeiro.txt da lojinha mora assim:
/home/ana/loja/vendas/janeiro.txt
Lendo da esquerda para a direita: começando da raiz do disco (a primeira /), entre na pasta home, depois na pasta ana, depois em loja, depois em vendas, e lá dentro está o arquivo janeiro.txt. Esse "endereço" se chama caminho (em inglês, path). Cada / separa uma pasta da próxima.
| Tipo de caminho | Exemplo | Quer dizer |
|---|---|---|
| Absoluto (completo) | /home/ana/loja/produtos.txt | O endereço inteiro, a partir da raiz do disco. Começa com / |
| Relativo | loja/produtos.txt | "A partir de onde eu estou agora": a pasta loja que está na pasta atual |
Quando você roda python3 programa.py no terminal da Ana, a "pasta atual" é a pasta em que o terminal está (no começo, /home/ana). No editor do guia, é a pasta do programa. Nos exemplos desta aula, quase todos os caminhos são relativos: funcionam igual nos dois lugares.
1. O primeiro Path
Dentro do módulo pathlib mora o Path ("caminho"). Você o traz para o seu programa com from pathlib import Path (a aula Módulos e import explica essa linha em detalhe) e cria um caminho passando o texto dele:
from pathlib import Path
arquivo = Path("compras.txt")
print(arquivo)
print(type(arquivo))
- from pathlib import Path
- "Do módulo
pathlib, traga oPath." Sem essa linha, o Python não conhece o nomePath. - Path("compras.txt")
- Cria um objeto caminho a partir do texto
"compras.txt". Ele ainda não abre nem cria nada: é só o endereço, anotado num papel. - arquivo = …
- Guarda o caminho na variável
arquivo, como qualquer outro valor. - print(arquivo)
- Mostra o caminho como texto.
$ python3 caminho.py compras.txt <class 'pathlib.PosixPath'>
O print mostrou o caminho sem aspas, e o type revelou que ele não é um texto (str), e sim um PosixPath: um caminho no estilo do Linux e do macOS (POSIX é o nome do padrão que esses sistemas seguem). No Windows, o mesmo programa mostraria WindowsPath. Você não precisa escolher: escreva sempre Path, e o Python usa o tipo certo para o sistema.
Repare que não existe nenhum compras.txt na pasta da Ana, e mesmo assim o programa funcionou. Criar um Path é como anotar um endereço: anotar não constrói a casa. O erro só aparece quando você tenta usar o arquivo (ler, por exemplo), como você vai ver em Quando dá errado.
2. Juntando pedaços com a barra /
O jeito mais bonito do pathlib é a barra. Entre um Path e um texto, o / não é divisão: é "entre nesta pasta". Assim você monta um caminho pedaço por pedaço:
from pathlib import Path
pasta = Path("loja")
arquivo = pasta / "vendas" / "janeiro.txt"
print(arquivo)
print("Nome:", arquivo.name)
print("Sem a extensão:", arquivo.stem)
print("Extensão:", arquivo.suffix)
print("Pasta onde está:", arquivo.parent)
print("Partes:", arquivo.parts)
$ python3 partes.py
loja/vendas/janeiro.txt
Nome: janeiro.txt
Sem a extensão: janeiro
Extensão: .txt
Pasta onde está: loja/vendas
Partes: ('loja', 'vendas', 'janeiro.txt')
- pasta / "vendas"
- Um
Pathbarra um texto dá umPathnovo:loja/vendas. Dá para encadear quantas barras quiser. - .name
- O nome do último pedaço, com a extensão:
janeiro.txt. - .stem
- O nome sem a extensão (stem = "talo", a parte principal):
janeiro. - .suffix
- A extensão, com o ponto (suffix = "sufixo"):
.txt. - .parent
- A pasta "mãe", onde o arquivo está (parent = "pai/mãe"):
loja/vendas. Também é umPath. - .parts
- Todos os pedaços, numa tupla.
Repare: name, stem, suffix e parent não levam parênteses. Eles não fazem nada no disco; só leem pedaços do próprio endereço. São atributos, informações que o objeto já tem.
"loja/vendas/janeiro.txt" de uma vez?
Funciona no Linux, mas o Windows separa as pastas com a barra invertida (loja\vendas\janeiro.txt). Com Path("loja") / "vendas" / "janeiro.txt", o Python escreve o separador certo para cada sistema, e o seu programa roda nos dois sem mudar uma letra.
Missão: a Ana guardou as vendas de março no arquivo marco.txt, dentro da pasta 2026, que fica dentro de vendas, que fica dentro de loja. Monte esse caminho com barras / a partir de Path("loja") e rode: o programa deve mostrar o caminho e a extensão.
from pathlib import Path
arquivo = Path("loja")
print(arquivo)
print("Extensão:", arquivo.suffix)
from pathlib import Path
arquivo = Path("loja") / "vendas" / "2026" / "marco.txt"
print(arquivo)
print("Extensão:", arquivo.suffix)
3. Onde eu estou? cwd(), home() e absolute()
Três perguntas que o Path responde sobre o computador:
from pathlib import Path
print("Pasta atual:", Path.cwd())
print("Pasta pessoal:", Path.home())
arquivo = Path("compras.txt")
print("Caminho completo:", arquivo.absolute())
$ python3 onde.py Pasta atual: /home/ana Pasta pessoal: /home/ana Caminho completo: /home/ana/compras.txt
| Escrita | O que responde |
|---|---|
Path.cwd() | A pasta atual (current working directory, "pasta de trabalho atual"): de onde partem os caminhos relativos |
Path.home() | A pasta pessoal do usuário: /home/ana para a Ana |
caminho.absolute() | O caminho relativo transformado em absoluto, grudando a pasta atual na frente |
Esses três dependem do computador: num outro usuário, ou no editor do guia, as respostas são outras. Por isso eles servem para mostrar onde as coisas estão, mas um programa que você vai mandar para outras pessoas não deve ter /home/ana escrito dentro dele.
4. Existe? É arquivo? É pasta?
Antes de abrir um arquivo, dá para perguntar se ele está lá. As respostas são booleanos (True ou False):
from pathlib import Path
for nome in ["Documentos", "compras.txt", "existe.py"]:
caminho = Path(nome)
print(nome)
print(" existe?", caminho.exists())
print(" é arquivo?", caminho.is_file())
print(" é pasta?", caminho.is_dir())
$ python3 existe.py Documentos existe? True é arquivo? False é pasta? True compras.txt existe? False é arquivo? False é pasta? False existe.py existe? True é arquivo? True é pasta? False
- .exists()
- "Existe?" Verdadeiro se houver qualquer coisa com esse nome: arquivo ou pasta.
- .is_file()
- "É um arquivo?" Falso para pastas e para o que não existe.
- .is_dir()
- "É uma pasta?" (dir vem de directory, "diretório", outro nome para pasta.)
Esses levam parênteses: são métodos, ações que vão até o disco olhar. A pasta Documentos existe e é pasta; compras.txt não existe, então as três respostas são False; e o próprio programa existe.py é um arquivo.
O uso mais comum é num if, para não tentar ler o que não está lá:
from pathlib import Path
arquivo = Path("loja") / "produtos.txt"
if arquivo.exists():
print(arquivo.read_text(encoding="utf-8"))
else:
print("Ainda não existe a lista de produtos.")
Rodando agora, que a lista ainda não foi criada, e depois da seção 6, quando ela já existir:
$ python3 conferir.py « antes de existir o loja/produtos.txt Ainda não existe a lista de produtos. $ python3 conferir.py « depois café açúcar pão de queijo
5. Criando pastas: mkdir()
mkdir vem de make directory, "criar pasta" (o mesmo nome do comando do terminal). A Ana vai criar a pasta da loja e, dentro dela, vendas/2026:
from pathlib import Path
loja = Path("loja")
loja.mkdir()
print("Criei a pasta", loja)
vendas = loja / "vendas" / "2026"
vendas.mkdir(parents=True)
print("Criei a pasta", vendas)
loja.mkdir(exist_ok=True)
print("A pasta loja já existia, e tudo bem")
$ python3 pastas.py
Criei a pasta loja
Criei a pasta loja/vendas/2026
A pasta loja já existia, e tudo bem
$ tree loja « o comando tree desenha as pastas
loja
└── vendas
└── 2026
3 directories, 0 files
- loja.mkdir()
- Cria uma pasta. A pasta de cima tem de existir (aqui é a pasta atual, que existe).
- mkdir(parents=True)
- Cria também as pastas do meio que faltarem (parents = "os pais"). Sem isso, criar
loja/vendas/2026daria erro, porquevendasainda não existia. - mkdir(exist_ok=True)
- "Tudo bem se já existir" (exist ok). Sem isso, criar uma pasta que já existe dá erro.
O tree ("árvore") é um programa do terminal que desenha as pastas uma dentro da outra; a última linha (em inglês) conta 3 pastas e nenhum arquivo. E se a Ana rodar o programa de novo? A primeira linha, loja.mkdir(), sem exist_ok, tenta criar uma pasta que agora existe:
$ python3 pastas.py
Traceback (most recent call last):
File "/home/ana/pastas.py", line 4, in <module>
loja.mkdir()
~~~~~~~~~~^^
File "/usr/lib/python3.14/pathlib/__init__.py", line 1012, in mkdir
os.mkdir(self, mode)
~~~~~~~~^^^^^^^^^^^^
FileExistsError: [Errno 17] File exists: 'loja'
Leia o traceback de baixo para cima. A última linha é o que aconteceu: FileExistsError, "erro: o arquivo existe", File exists: 'loja'. Para o sistema, uma pasta também é um tipo de "arquivo", por isso a mensagem fala em file. Acima dela há dois trechos de código: o primeiro é a linha 4 do programa da Ana (loja.mkdir()); o segundo é de dentro do próprio pathlib, onde o erro de fato estourou. Quando o traceback passa por arquivos do Python (os que começam com /usr/lib/python3.14/), procure a última linha que é sua: é ela que você conserta.
A receita que não falha, e que você vai ver em muitos programas, é juntar as duas opções:
from pathlib import Path
Path("loja", "vendas", "2026").mkdir(parents=True, exist_ok=True)
print("Pronto, e sem erro")
$ python3 receita.py Pronto, e sem erro $ python3 receita.py « de novo: nada de FileExistsError Pronto, e sem erro
Cria o que faltar e não reclama do que já existe. (Repare em mais um jeito de montar o caminho: Path("loja", "vendas", "2026"), com os pedaços separados por vírgula, é o mesmo que Path("loja") / "vendas" / "2026".)
6. Ler e gravar sem open(): read_text() e write_text()
Para arquivos de texto pequenos, o Path tem dois atalhos que fazem o open, o with, o read/write e o fechamento numa linha só:
from pathlib import Path
arquivo = Path("loja") / "produtos.txt"
arquivo.write_text("café\naçúcar\npão de queijo\n", encoding="utf-8")
print("Gravei", arquivo)
texto = arquivo.read_text(encoding="utf-8")
print(texto)
print("O arquivo tem", len(texto.splitlines()), "linhas")
$ python3 escrever.py Gravei loja/produtos.txt café açúcar pão de queijo O arquivo tem 3 linhas $ cat loja/produtos.txt « o cat do terminal mostra o arquivo gravado café açúcar pão de queijo
- arquivo.write_text(texto, encoding="utf-8")
- "Escreva este texto": cria o arquivo (ou apaga o conteúdo antigo e escreve por cima, como o modo
"w"doopen), grava e fecha. - arquivo.read_text(encoding="utf-8")
- "Leia o texto": abre, lê tudo num
strsó e fecha. - encoding="utf-8"
- A codificação, que diz como os acentos viram bytes. Sempre escreva, como você aprendeu em Abrindo Arquivos: assim o "café" chega inteiro em qualquer computador.
A linha em branco depois de "pão de queijo" é o \n do fim do arquivo somado ao \n do próprio print. O splitlines() quebra o texto nas linhas e o len conta: 3.
| Quero… | Com open | Com Path |
|---|---|---|
| Ler tudo de uma vez | with open(p, encoding="utf-8") as f: | texto = p.read_text(encoding="utf-8") |
| Gravar tudo de uma vez | with open(p, "w", encoding="utf-8") as f: | p.write_text(texto, encoding="utf-8") |
Ler linha por linha, acrescentar no fim ("a"), arquivos grandes | with open(p, …) as f: | with p.open(…) as f: (o mesmo open, chamado pelo caminho) |
O open() aceita um Path no lugar do texto do nome: open(arquivo, encoding="utf-8") funciona. Tudo o que você aprendeu em Lendo Arquivos e Escrevendo Arquivos continua valendo.
Missão: o programa quer gravar a lista de compras em mercado/lista.txt, mas a pasta mercado não existe e ele dá FileNotFoundError. Rode para ver o erro e conserte: crie a pasta antes de gravar.
from pathlib import Path
pasta = Path("mercado")
lista = pasta / "lista.txt"
lista.write_text("arroz\nfeijão\n", encoding="utf-8")
print(lista.read_text(encoding="utf-8"))
from pathlib import Path
pasta = Path("mercado")
lista = pasta / "lista.txt"
pasta.mkdir(exist_ok=True)
lista.write_text("arroz\nfeijão\n", encoding="utf-8")
print(lista.read_text(encoding="utf-8"))
7. O que tem dentro da pasta? iterdir()
A loja da Ana foi crescendo. Ela criou mais alguns arquivos (aqui com o touch do terminal, que cria arquivos vazios) e o tree mostra como ficou:
$ touch loja/clientes.txt loja/vendas/janeiro.txt loja/vendas/fevereiro.txt loja/vendas/notas.csv loja/vendas/2026/marco.txt
$ tree loja
loja
├── clientes.txt
├── produtos.txt
└── vendas
├── 2026
│ └── marco.txt
├── fevereiro.txt
├── janeiro.txt
└── notas.csv
3 directories, 6 files
Para o programa descobrir o que tem dentro de uma pasta, use iterdir() (de iterate directory, "percorrer a pasta"). Ele entrega um Path para cada coisa que está diretamente dentro da pasta:
from pathlib import Path
loja = Path("loja")
for item in sorted(loja.iterdir()):
if item.is_dir():
print("[pasta] ", item.name)
else:
print("[arquivo]", item.name)
$ python3 listar.py [arquivo] clientes.txt [arquivo] produtos.txt [pasta] vendas
- loja.iterdir()
- Os itens que estão dentro de
loja, um por vez, cada um como umPath(loja/clientes.txt,loja/vendas…). Não entra nas subpastas: o que está dentro devendasnão aparece. - sorted(…)
- Coloca em ordem alfabética (aula Ordenando Listas).
- item.is_dir()
- Separa as pastas dos arquivos.
- item.name
- Só o nome, sem o
loja/na frente.
sorted, a ordem é a do disco
O iterdir() entrega os itens na ordem em que o sistema guardou, que não é alfabética e pode mudar de um computador para outro. Se a ordem importa (quase sempre importa, para quem lê), passe por sorted().
8. Procurando arquivos: glob() e rglob()
E se a Ana quiser só os arquivos .txt? O glob procura pelos nomes que combinam com um molde, onde o * quer dizer "qualquer coisa" (é o mesmo curinga do terminal: ls *.txt).
from pathlib import Path
loja = Path("loja")
print("Os .txt da pasta loja:")
for arquivo in sorted(loja.glob("*.txt")):
print(" ", arquivo)
print("Os .txt em qualquer lugar dentro de loja:")
for arquivo in sorted(loja.rglob("*.txt")):
print(" ", arquivo)
$ python3 procurar.py Os .txt da pasta loja: loja/clientes.txt loja/produtos.txt Os .txt em qualquer lugar dentro de loja: loja/clientes.txt loja/produtos.txt loja/vendas/2026/marco.txt loja/vendas/fevereiro.txt loja/vendas/janeiro.txt
| Molde | Encontra |
|---|---|
loja.glob("*.txt") | Os nomes terminados em .txt direto em loja |
loja.glob("*") | Tudo o que está direto em loja (parecido com iterdir()) |
loja.glob("vendas/*.csv") | Os .csv dentro de loja/vendas |
loja.glob("*a*") | Os nomes que têm a letra a em qualquer lugar |
loja.glob("vendas/janeiro.???") | ? é exatamente um caractere qualquer: janeiro.txt, janeiro.csv… |
loja.rglob("*.txt") | Os .txt em loja e em todas as subpastas, até o fundo (r de recursive, "recursivo") |
O notas.csv não apareceu em nenhuma das duas buscas: o molde pedia .txt. E o rglob desceu até vendas/2026/marco.txt, que o glob não enxerga. Como no iterdir, use sorted() para ter uma ordem garantida.
9. Apagando: unlink() e rmdir()
from pathlib import Path
rascunho = Path("loja") / "rascunho.txt"
rascunho.write_text("teste\n", encoding="utf-8")
print("Existe?", rascunho.exists())
rascunho.unlink()
print("Depois do unlink, existe?", rascunho.exists())
rascunho.unlink(missing_ok=True)
print("Apagar de novo, com missing_ok=True, não deu erro")
vazia = Path("loja") / "vazia"
vazia.mkdir()
vazia.rmdir()
print("A pasta vazia foi apagada:", not vazia.exists())
$ python3 apagar.py Existe? True Depois do unlink, existe? False Apagar de novo, com missing_ok=True, não deu erro A pasta vazia foi apagada: True
- .unlink()
- Apaga um arquivo (unlink = "desligar", o nome técnico de apagar no Linux). Se o arquivo não existir, dá
FileNotFoundError. - .unlink(missing_ok=True)
- "Tudo bem se estiver faltando": não reclama se o arquivo já não existe.
- .rmdir()
- Apaga uma pasta vazia (remove directory). Com qualquer coisa dentro, ela se recusa.
O unlink() não manda o arquivo para a lixeira: ele some de vez, sem pergunta. Antes de rodar um programa que apaga arquivos, confira o caminho com um print. Que o rmdir() só apague pastas vazias é uma proteção a seu favor.
Formas diferentes de montar um caminho
Antes do pathlib (que existe desde o Python 3.4), os caminhos eram textos comuns, montados com a função os.path.join. Você ainda vai encontrar muito código assim:
import os.path
from pathlib import Path
jeito_antigo = os.path.join("loja", "vendas", "janeiro.txt")
jeito_novo = Path("loja") / "vendas" / "janeiro.txt"
print(jeito_antigo, type(jeito_antigo))
print(jeito_novo, type(jeito_novo))
print(str(jeito_novo) == jeito_antigo)
$ python3 ospath.py loja/vendas/janeiro.txt <class 'str'> loja/vendas/janeiro.txt <class 'pathlib.PosixPath'> True
O mesmo endereço, só que um é texto e o outro é um Path. O str(caminho) transforma o Path em texto quando alguma função antiga exigir.
| Forma | Quando usar |
|---|---|
Path("loja") / "vendas" / "janeiro.txt" | O jeito moderno e o do guia. Fácil de ler, funciona em qualquer sistema e já dá acesso a name, exists(), read_text()… |
Path("loja", "vendas", "janeiro.txt") | O mesmo caminho; prático quando os pedaços já estão separados |
Path("loja/vendas/janeiro.txt") | Funciona; o Path entende a / no texto, até no Windows. Bom para caminhos fixos e curtos |
os.path.join("loja", "vendas", "janeiro.txt") | Código antigo. Funciona, mas devolve um texto e não tem os métodos do Path |
"loja" + "/" + "janeiro.txt" | Evite: é fácil esquecer ou dobrar a barra, e no Windows o separador é outro |
No Python 3.13 (o do Debian 13), o type() de um caminho aparece como <class 'pathlib._local.PosixPath'>, com um _local no meio. É só o lugar onde a classe mora por dentro; o uso é idêntico.
Quando dá errado
FileNotFoundError
from pathlib import Path
arquivo = Path("loja") / "precos.txt"
texto = arquivo.read_text(encoding="utf-8")
print(texto)
$ python3 ler_falta.py
Traceback (most recent call last):
File "/home/ana/ler_falta.py", line 4, in <module>
texto = arquivo.read_text(encoding="utf-8")
File "/usr/lib/python3.14/pathlib/__init__.py", line 788, in read_text
with self.open(mode='r', encoding=encoding, errors=errors, newline=newline) as f:
~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3.14/pathlib/__init__.py", line 772, in open
return io.open(self, mode, buffering, encoding, errors, newline)
~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
FileNotFoundError: [Errno 2] No such file or directory: 'loja/precos.txt'
Um traceback comprido, mas só a primeira e a última parte interessam:
File "/home/ana/ler_falta.py", line 4: o problema começou na linha 4 do seu programa, oread_text.- As duas partes do meio (
/usr/lib/python3.14/pathlib/…) são o caminho que o erro fez dentro dopathlib: oread_textchamou oopen, que chamou oio.open. Não é ali que você conserta. FileNotFoundError: [Errno 2] No such file or directory: 'loja/precos.txt': "arquivo não encontrado: não existe esse arquivo ou pasta". O[Errno 2]é o número que o sistema dá para esse erro.
Como consertar: confira o nome (era produtos.txt?) e a pasta atual; ou pergunte antes com if arquivo.exists():; ou trate o erro com try/except FileNotFoundError (aula try e except).
TypeError
caminho = "loja" / "produtos.txt" print(caminho)
$ python3 barra_texto.py
Traceback (most recent call last):
File "/home/ana/barra_texto.py", line 1, in <module>
caminho = "loja" / "produtos.txt"
~~~~~~~^~~~~~~~~~~~~~~~
TypeError: unsupported operand type(s) for /: 'str' and 'str'
"Tipos de operando não suportados para /: str e str." O ^ embaixo aponta para a barra. A barra só vira "entrar na pasta" quando pelo menos um dos lados é um Path; entre dois textos, ela é a divisão, e texto não se divide. Como consertar: comece com um Path: Path("loja") / "produtos.txt".
Path: AttributeError
arquivo = "loja/produtos.txt" print(arquivo.exists())
$ python3 texto_exists.py
Traceback (most recent call last):
File "/home/ana/texto_exists.py", line 2, in <module>
print(arquivo.exists())
^^^^^^^^^^^^^^
AttributeError: 'str' object has no attribute 'exists'
"Objeto str não tem o atributo exists." A variável guarda um texto, e texto não sabe perguntar ao disco nada. Como consertar: arquivo = Path("loja/produtos.txt").
import: NameError
arquivo = Path("compras.txt")
print(arquivo)
$ python3 sem_import.py
Traceback (most recent call last):
File "/home/ana/sem_import.py", line 1, in <module>
arquivo = Path("compras.txt")
^^^^
NameError: name 'Path' is not defined
"O nome Path não está definido." O Path não vem pronto como o print: ele mora no módulo pathlib. Como consertar: from pathlib import Path no começo do programa.
IsADirectoryError
from pathlib import Path
print(Path("loja").read_text(encoding="utf-8"))
$ python3 ler_pasta.py
Traceback (most recent call last):
File "/home/ana/ler_pasta.py", line 3, in <module>
print(Path("loja").read_text(encoding="utf-8"))
~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3.14/pathlib/__init__.py", line 788, in read_text
with self.open(mode='r', encoding=encoding, errors=errors, newline=newline) as f:
~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3.14/pathlib/__init__.py", line 772, in open
return io.open(self, mode, buffering, encoding, errors, newline)
~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
IsADirectoryError: [Errno 21] Is a directory: 'loja'
"É uma pasta: 'loja'." Pasta não tem texto para ler; o que ela tem são outros arquivos. Como consertar: leia um arquivo de dentro dela (Path("loja") / "produtos.txt") ou liste o conteúdo com iterdir().
from pathlib import Path
Path("loja").rmdir()
$ python3 rmdir_cheia.py
Traceback (most recent call last):
File "/home/ana/rmdir_cheia.py", line 3, in <module>
Path("loja").rmdir()
~~~~~~~~~~~~~~~~~~^^
File "/usr/lib/python3.14/pathlib/__init__.py", line 1052, in rmdir
os.rmdir(self)
~~~~~~~~^^^^^^
OSError: [Errno 39] Directory not empty: 'loja'
"Pasta não está vazia." Desta vez o erro é o OSError genérico, "erro do sistema operacional". Como consertar: apague primeiro o que está dentro (com unlink(), arquivo por arquivo) e só então a pasta. Para apagar uma pasta inteira com tudo dentro existe o shutil.rmtree, do módulo shutil; use com muito cuidado, porque ele não pergunta nada.
FileExistsError
Você já viu este na seção 5: rodar Path("loja").mkdir() pela segunda vez dá FileExistsError: [Errno 17] File exists: 'loja'. Como consertar: mkdir(exist_ok=True).
FileNotFoundError no mkdir
from pathlib import Path
pasta = Path("arquivo_morto") / "2026"
pasta.mkdir()
$ python3 sem_parents.py
Traceback (most recent call last):
File "/home/ana/sem_parents.py", line 4, in <module>
pasta.mkdir()
~~~~~~~~~~~^^
File "/usr/lib/python3.14/pathlib/__init__.py", line 1012, in mkdir
os.mkdir(self, mode)
~~~~~~~~^^^^^^^^^^^^
FileNotFoundError: [Errno 2] No such file or directory: 'arquivo_morto/2026'
Parece estranho: "não existe" é justamente o que você quer criar! Mas o que falta é a pasta de cima, arquivo_morto: o mkdir() sozinho cria só o último pedaço. Como consertar: mkdir(parents=True).
Missão: o programa quer criar arquivo_morto/2026 de uma vez, mas a pasta arquivo_morto ainda não existe. Rode, leia o erro e conserte com a opção certa do mkdir.
from pathlib import Path
pasta = Path("arquivo_morto") / "2026"
pasta.mkdir()
print("Pasta criada:", pasta.name, "é pasta?", pasta.is_dir())
from pathlib import Path
pasta = Path("arquivo_morto") / "2026"
pasta.mkdir(parents=True)
print("Pasta criada:", pasta.name, "é pasta?", pasta.is_dir())
Referência rápida
| Escrita | O que faz |
|---|---|
from pathlib import Path | Traz o Path para o programa |
Path("loja") | Cria um caminho (não mexe no disco) |
p / "vendas" / "jan.txt" | Junta pedaços: um caminho dentro do outro |
p.name, p.stem, p.suffix | Nome com extensão, nome sem extensão, extensão |
p.parent, p.parts | A pasta de cima; todos os pedaços numa tupla |
Path.cwd(), Path.home(), p.absolute() | Pasta atual; pasta pessoal; caminho completo |
p.exists(), p.is_file(), p.is_dir() | Existe? É arquivo? É pasta? |
p.mkdir(parents=True, exist_ok=True) | Cria a pasta (e as do meio), sem reclamar se já existir |
p.read_text(encoding="utf-8") | Lê o arquivo inteiro num texto |
p.write_text(texto, encoding="utf-8") | Grava o texto, apagando o conteúdo antigo |
p.open(…) | O mesmo que open(p, …) |
sorted(p.iterdir()) | O que está direto dentro da pasta, em ordem |
sorted(p.glob("*.txt")) | Os nomes que combinam com o molde, direto na pasta |
sorted(p.rglob("*.txt")) | …na pasta e em todas as subpastas |
p.unlink(missing_ok=True) | Apaga o arquivo (para sempre) |
p.rmdir() | Apaga a pasta, se estiver vazia |
str(p) | O caminho como texto |
| Mensagem | Causa provável |
|---|---|
FileNotFoundError: [Errno 2] No such file or directory | Arquivo (ou pasta de cima) não existe: nome errado, pasta atual errada, faltou parents=True |
FileExistsError: [Errno 17] File exists | mkdir() numa pasta que já existe: use exist_ok=True |
IsADirectoryError: [Errno 21] Is a directory | Tentou ler uma pasta como se fosse arquivo |
OSError: [Errno 39] Directory not empty | rmdir() numa pasta com coisas dentro |
TypeError: unsupported operand type(s) for /: 'str' and 'str' | Barra entre dois textos: comece com Path(…) |
AttributeError: 'str' object has no attribute 'exists' | A variável é um texto, não um Path |
NameError: name 'Path' is not defined | Faltou from pathlib import Path |
Exercícios
1. Juntando os pedaços
Complete para montar o caminho loja/clientes.txt:
2. A extensão
Para arquivo = Path("vendas/notas.csv"), o que mostra print(arquivo.suffix)?
3. Criar sem reclamar
Complete para criar loja/vendas/2027, inclusive as pastas do meio, sem erro se já existir:
4. A pasta atual não tem nenhum agenda.txt. O que acontece com p = Path("agenda.txt")?
5. A pasta loja tem produtos.txt e a subpasta vendas, com janeiro.txt. O que sorted(Path("loja").glob("*.txt")) encontra?
6. Qual linha dá TypeError?
Missão final: só os arquivos de texto
Missão: o começo do programa monta uma pasta loja com quatro coisas dentro. Do jeito que está, ele lista tudo. Troque o iterdir() por um glob que pegue só os .txt, e a última linha deve contar quantos são: 2 arquivos .txt.
from pathlib import Path
# Montando a pasta da loja (não precisa mexer aqui)
loja = Path("loja")
(loja / "fotos").mkdir(parents=True, exist_ok=True)
(loja / "produtos.txt").write_text("café\n", encoding="utf-8")
(loja / "clientes.txt").write_text("Bia\n", encoding="utf-8")
(loja / "notas.csv").write_text("nome;nota\n", encoding="utf-8")
# A partir daqui é com você
achados = sorted(loja.iterdir())
for arquivo in achados:
print(arquivo)
print(len(achados), "arquivos .txt")
from pathlib import Path
# Montando a pasta da loja (não precisa mexer aqui)
loja = Path("loja")
(loja / "fotos").mkdir(parents=True, exist_ok=True)
(loja / "produtos.txt").write_text("café\n", encoding="utf-8")
(loja / "clientes.txt").write_text("Bia\n", encoding="utf-8")
(loja / "notas.csv").write_text("nome;nota\n", encoding="utf-8")
# A partir daqui é com você
achados = sorted(loja.glob("*.txt"))
for arquivo in achados:
print(arquivo)
print(len(achados), "arquivos .txt")
Repare nos parênteses em (loja / "fotos").mkdir(…): primeiro a barra monta o caminho, depois o mkdir age sobre ele. Sem os parênteses, o Python tentaria fazer "fotos".mkdir(), e texto não tem mkdir.
Resumo
- Um caminho é o endereço de um arquivo ou pasta.
from pathlib import PathePath("loja")criam um, sem mexer no disco. - A barra
/entre umPathe um texto junta pedaços:Path("loja") / "vendas" / "janeiro.txt", com o separador certo em qualquer sistema. Entre dois textos, ela dáTypeError. name,stem,suffix,parentleem pedaços do endereço (sem parênteses).exists(),is_file(),is_dir()perguntam ao disco.mkdir(parents=True, exist_ok=True)cria a pasta e as do meio, sem reclamar se já existir.read_text()ewrite_text()leem e gravam o arquivo inteiro numa linha; sempre comencoding="utf-8".iterdir()lista a pasta;glob("*.txt")procura direto nela;rglobdesce às subpastas. Usesorted()para ter ordem.unlink()apaga um arquivo para sempre;rmdir()só apaga pasta vazia.- No traceback, procure a última linha que é do seu programa; as de
/usr/lib/python3.14/são de dentro do Python.