Python open e with

Tudo o que seus programas guardaram até agora sumia quando eles terminavam: as notas da turma, a lista de compras, o saldo. Para guardar uma informação de um dia para o outro, o programa precisa escrevê-la num arquivo, e para usá-la depois, abrir e ler esse arquivo. Nesta aula você aprende o primeiro passo, que vale para ler e para escrever: abrir um arquivo com open() (em inglês, "abrir") e fechá-lo do jeito certo, com with.

Você vai aprender
  • A abrir um arquivo de texto com open(), ler o conteúdo e fechar com close().
  • Por que o with é o jeito recomendado: ele fecha o arquivo sozinho.
  • Para que serve o encoding="utf-8" e o que acontece com os acentos sem ele (principalmente no Windows).
  • Os modos de abrir: "r" (ler), "w" (escrever do zero), "a" (acrescentar) e "x" (criar novo).
  • O FileNotFoundError e como tratá-lo.
  • Os caminhos relativos: por que o arquivo é procurado na pasta onde você roda o programa, e não onde o programa está.

Todos os programas desta aula rodaram no Python 3.14 da máquina da Ana (usuária ana, computador notebook, Ubuntu), salvos na pasta pessoal dela, /home/ana. Os detalhes de ler (Lendo Arquivos) e de escrever (Escrevendo Arquivos) têm aulas próprias; aqui o assunto é abrir.


A ideia: o caderno na gaveta

A professora da Ana guarda as notas da turma num caderno, dentro de uma gaveta. Para usar o caderno, ela:

  1. Abre a gaveta e pega o caderno, já decidindo para quê: só para consultar, para começar uma página nova ou para acrescentar no fim.
  2. Lê ou escreve.
  3. Guarda o caderno de volta e fecha a gaveta.

Com arquivos é igual. O open() é o passo 1: você diz qual arquivo e para quê (o "modo"). Depois lê ou escreve. Por fim, fecha o arquivo, para o sistema saber que você terminou e para tudo o que você escreveu ser gravado de verdade. Se a professora esquece o caderno aberto em cima da mesa, alguém pode não achá-lo na gaveta; um arquivo que fica aberto também pode causar problemas.

Os arquivos desta aula são arquivos de texto (.txt): só letras, números e quebras de linha, do tipo que você abre no Bloco de Notas, no gedit ou no nano. Este é o arquivo notas.txt da Ana, mostrado no terminal com o comando cat:

$ cat notas.txt
Ana: 9.0
Bruno: 6.5
Carla: 8.5

1. Abrir, ler e fechar

arquivo = open("notas.txt", encoding="utf-8")
conteudo = arquivo.read()
arquivo.close()
print(conteudo)
open("notas.txt", …)
Abre o arquivo notas.txt. O nome vai entre aspas, é um texto. Sem pasta na frente, o Python procura o arquivo na pasta atual (seção 6).
encoding="utf-8"
A "codificação": a regra para transformar os bytes do arquivo em letras. utf-8 é a regra usada por quase todos os arquivos hoje. A seção 3 explica por que vale escrever sempre.
arquivo = …
O open() devolve um objeto arquivo, a "alça" para mexer no arquivo aberto. A variável pode ter qualquer nome; arquivo e f (de file) são os mais comuns.
arquivo.read()
"Ler": devolve todo o conteúdo do arquivo como um único texto. Outras formas de ler estão em Lendo Arquivos.
arquivo.close()
"Fechar": avisa que você terminou. Depois disso, o objeto arquivo não serve mais para ler.
$ python3 abrir.py
Ana: 9.0
Bruno: 6.5
Carla: 8.5

O conteúdo apareceu. No terminal de verdade, ele ainda vem seguido de uma linha em branco (repare nela nas sessões abaixo, entre um programa e o próximo $). Ela vem do próprio arquivo: a última linha (Carla: 8.5) termina com uma quebra de linha, e o print acrescenta mais uma. A aula Lendo Arquivos mostra como tirar essa sobra.


2. with: o arquivo se fecha sozinho

O close() tem um problema: é fácil esquecer. E, se der um erro entre o open() e o close(), o programa para antes de chegar ao close(). O Python tem um jeito de abrir que garante o fechamento, o with (em inglês, "com"):

with open("notas.txt", encoding="utf-8") as arquivo:
    conteudo = arquivo.read()
    print(f"Dentro do with, fechado? {arquivo.closed}")
print(f"Depois do with, fechado? {arquivo.closed}")
print(conteudo)
with open(…) as arquivo:
"Com o arquivo aberto, chamado arquivo, faça o bloco abaixo." O as ("como") dá o nome à variável, como no except … as e da aula try e except. Termina com dois-pontos.
o bloco indentado
Enquanto o Python estiver nestas linhas (4 espaços para dentro), o arquivo está aberto.
arquivo.closed
Um atributo que diz se o arquivo está fechado: True ou False.
a linha que voltou para a margem
Saiu do bloco: o with fechou o arquivo sozinho. Não existe close() no programa.
$ python3 com_with.py
Dentro do with, fechado? False
Depois do with, fechado? True
Ana: 9.0
Bruno: 6.5
Carla: 8.5

Dentro do bloco, aberto; fora, fechado. E o conteudo continua disponível depois do bloco: o que foi lido já está guardado na variável. O with fecha o arquivo também quando acontece um erro dentro do bloco, do mesmo jeito que o finally da aula else e finally roda sempre. Por isso ele é o jeito recomendado de abrir arquivos, e é o único que o guia usa daqui em diante. (Como o with funciona por dentro está na aula Gerenciadores de Contexto.)

FormaFecha o arquivo?Quando usar
arquivo = open(…) … arquivo.close()Só se você lembrar, e só se não der erro antesRaramente; você vai ver em códigos antigos
with open(…) as arquivo:Sempre, ao sair do bloco, com erro ou semSempre

Missão: a aba compras.txt é a lista de compras da Ana, que fica na mesma pasta do programa. O main.py abre a lista do jeito antigo e sem encoding. Reescreva com with open("compras.txt", encoding="utf-8") as arquivo:, ponha a leitura e o print dentro do bloco e apague o close().

arquivo = open("compras.txt")
print(arquivo.read())
arquivo.close()
Lista de compras:
pão de queijo
maçã
feijão
café
with open("compras.txt", encoding="utf-8") as arquivo:
    print(arquivo.read())

3. encoding="utf-8": os acentos

Um arquivo, no disco, não guarda letras: guarda números (bytes). Para o ç virar bytes e voltar a ser ç, quem grava e quem lê têm de usar a mesma regra. Essa regra é a codificação (encoding). A mais usada no mundo, e a de quase todo arquivo novo, é a UTF-8. Com ela, a lista de compras sai certinha:

with open("compras.txt", encoding="utf-8") as arquivo:
    print(arquivo.read())
$ python3 acentos.py
Lista de compras:
pão de queijo
maçã
feijão
café

Agora o mesmo arquivo lido com outra regra, a cp1252, que é a codificação tradicional do Windows em português:

with open("compras.txt", encoding="cp1252") as arquivo:
    print(arquivo.read())
$ python3 errado_cp.py
Lista de compras:
pão de queijo
maçã
feijão
café

Nenhum erro, e todos os acentos viraram lixo: pão virou pão. Na UTF-8, cada letra acentuada ocupa dois bytes; a cp1252 leu cada byte como uma letra separada. Se você já viu um "ã" num e-mail ou num site, foi exatamente isso.

O contrário também acontece: um arquivo antigo, gravado em cp1252 (o antigo.txt, com a palavra maçã), lido como UTF-8:

with open("antigo.txt", encoding="utf-8") as arquivo:
    print(arquivo.read())
$ python3 le_antigo.py
Traceback (most recent call last):
  File "/home/ana/le_antigo.py", line 2, in <module>
    print(arquivo.read())
          ~~~~~~~~~~~~^^
  File "<frozen codecs>", line 325, in decode
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xe7 in position 2: invalid continuation byte

"O codec utf-8 não consegue decodificar o byte 0xe7 na posição 2." O byte 0xe7 é o ç na regra cp1252; na posição 2 (contando do zero: m, a, ç), a UTF-8 encontrou um byte que não faz sentido para ela. A linha File "<frozen codecs>" é de dentro do próprio Python (o código que traduz bytes em letras); o seu arquivo é a linha de cima. Como consertar: abrir com a codificação com que o arquivo foi gravado, encoding="cp1252".

E se eu não escrever o encoding?

Aí o Python usa a codificação padrão do sistema. No Ubuntu da Ana, ela é UTF-8, então funciona:

with open("compras.txt") as arquivo:
    print(arquivo.read())
$ python3 sem_encoding.py
Lista de compras:
pão de queijo
maçã
feijão
café

O problema é que o programa vai rodar em outros computadores. Num Windows em português, até o Python 3.14, o padrão costuma ser a cp1252: o mesmo programa, com o mesmo arquivo, mostraria pão. Funciona na sua máquina e quebra na do colega. Com encoding="utf-8" escrito, o resultado é o mesmo em qualquer sistema.

O Python até avisa, se você pedir. A opção -X warn_default_encoding mostra um aviso a cada open() sem encoding:

$ python3 -X warn_default_encoding sem_encoding.py
/home/ana/sem_encoding.py:1: EncodingWarning: 'encoding' argument not specified
  with open("compras.txt") as arquivo:
Lista de compras:
pão de queijo
maçã
feijão
café

"Aviso de codificação: o argumento encoding não foi informado", com o arquivo e a linha.

Python 3.15: UTF-8 por padrão em todo lugar

A partir do Python 3.15 (lançado em outubro de 2026), um open() sem encoding usa UTF-8 em qualquer sistema, inclusive no Windows (é a PEP 686). Mesmo assim, a própria documentação recomenda continuar escrevendo o encoding: assim o programa funciona igual no 3.15 e nos Pythons mais antigos, que ainda vão existir por muitos anos.


4. Os modos: ler, escrever, acrescentar, criar

O segundo argumento do open() é o modo: o "para quê" da gaveta. Quando você não escreve nenhum, ele é "r", de read (ler).

ModoEm inglêsPara quêSe o arquivo não existeSe o arquivo já existe
"r" (o padrão)readSó lerFileNotFoundErrorLê do começo
"w"writeEscrever do zeroCriaApaga tudo e começa vazio
"a"appendAcrescentar no fimCriaMantém o conteúdo e escreve depois dele
"x"exclusiveCriar um arquivo novoCriaFileExistsError: não apaga nada

Um programa que usa os três jeitos de escrever no recado do dia (o write(), "escrever", tem aula própria: Escrevendo Arquivos):

with open("recado.txt", "w", encoding="utf-8") as arquivo:
    arquivo.write("Comprar pão\n")
with open("recado.txt", "a", encoding="utf-8") as arquivo:
    arquivo.write("Pagar a luz\n")
with open("recado.txt", encoding="utf-8") as arquivo:
    print(arquivo.read())
$ python3 modos.py
Comprar pão
Pagar a luz

O "w" criou o arquivo com a primeira linha; o "a" acrescentou a segunda depois dela; o terceiro open(), sem modo, leu. Agora, cuidado com o "w" num arquivo que já existe:

with open("recado.txt", "w", encoding="utf-8") as arquivo:
    arquivo.write("Só isto agora\n")
with open("recado.txt", encoding="utf-8") as arquivo:
    print(arquivo.read())
$ python3 modo_w.py
Só isto agora

As duas linhas de antes sumiram, sem pergunta e sem aviso. O "w" esvazia o arquivo no momento em que o abre. Quando você quer criar um arquivo, mas nunca apagar um que já exista, use "x":

with open("recado.txt", "x", encoding="utf-8") as arquivo:
    arquivo.write("Não quero apagar nada\n")
$ python3 modo_x.py                              « a primeira vez: o recado.txt não existia
$ cat recado.txt
Não quero apagar nada
$ python3 modo_x.py                              « a segunda vez: ele já existe
Traceback (most recent call last):
  File "/home/ana/modo_x.py", line 1, in <module>
    with open("recado.txt", "x", encoding="utf-8") as arquivo:
         ~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
FileExistsError: [Errno 17] File exists: 'recado.txt'

Na primeira vez, o programa criou o arquivo sem dizer nada. Na segunda, recusou: "O arquivo existe." É um erro que você pode tratar com except FileExistsError, por exemplo para perguntar se a pessoa quer mesmo substituir.

Missão: o programa quer criar o diário da Ana, mas abre o arquivo no modo de ler, e o diario.txt ainda não existe. Rode para ver o erro e troque o modo para o de escrever do zero.

with open("diario.txt", "r", encoding="utf-8") as arquivo:
    arquivo.write("Hoje fez sol.\n")
print("Diário salvo.")
with open("diario.txt", "w", encoding="utf-8") as arquivo:
    arquivo.write("Hoje fez sol.\n")
print("Diário salvo.")

5. FileNotFoundError: o arquivo não está lá

O erro que mais aparece com arquivos. A Ana tentou abrir as notas do ano passado, que ela não tem:

with open("notas_2025.txt", encoding="utf-8") as arquivo:
    print(arquivo.read())
$ python3 nao_existe.py
Traceback (most recent call last):
  File "/home/ana/nao_existe.py", line 1, in <module>
    with open("notas_2025.txt", encoding="utf-8") as arquivo:
         ~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
FileNotFoundError: [Errno 2] No such file or directory: 'notas_2025.txt'

"Arquivo ou diretório inexistente: 'notas_2025.txt'." O [Errno 2] é o número que o sistema operacional dá a esse problema. (No editor do guia, que roda o Python dentro do navegador, o mesmo erro sai como [Errno 44]: lá o "sistema" é outro e numera os problemas de outro jeito. O tipo e a mensagem são os mesmos.) A mensagem mostra o nome exatamente como o programa pediu: confira letra por letra, maiúsculas, a extensão (.txt) e a pasta. No Linux, Notas.txt e notas.txt são arquivos diferentes.

Quando o nome vem do usuário, o certo é tratar o erro, com o try/except da aula try e except:

nome = input("Qual arquivo? ")
try:
    with open(nome, encoding="utf-8") as arquivo:
        print(arquivo.read())
except FileNotFoundError:
    print(f"Não achei o arquivo {nome}. Confira o nome e a pasta.")
$ python3 trata.py
Qual arquivo? notas.txt
Não achei o arquivo notas.txt. Confira o nome e a pasta.
$ python3 trata.py
Qual arquivo? escola/notas.txt
Ana: 9.0
Bruno: 6.5
Carla: 8.5

Na primeira vez, não havia notas.txt na pasta da Ana (ela tinha mudado as notas para a pasta escola). Na segunda, ela disse a pasta junto com o nome, escola/notas.txt, e funcionou. Isso leva ao último assunto da aula.


6. Caminhos: onde o Python procura o arquivo

Quando você escreve só "notas.txt", sem pasta, o Python procura o arquivo na pasta atual (em inglês, current working directory): a pasta em que o terminal estava quando você rodou o programa. Não é, necessariamente, a pasta onde o programa está guardado. Um nome assim, que depende da pasta atual, é um caminho relativo.

A Ana tem duas listas de notas: a deste ano, /home/ana/escola/notas.txt, ao lado do programa, e a do ano passado, esquecida na pasta pessoal, /home/ana/notas.txt:

$ cat notas.txt
Notas do ano passado:
Ana: 7.0
$ cat escola/notas.txt
Ana: 9.0
Bruno: 6.5
Carla: 8.5

O programa escola/onde.py mostra a pasta atual (com os.getcwd(), "pegue a pasta de trabalho atual"; o módulo os tem aula própria, Os Módulos os e sys) e abre notas.txt:

import os

print(f"Estou rodando na pasta: {os.getcwd()}")
with open("notas.txt", encoding="utf-8") as arquivo:
    print(arquivo.read())

O mesmo programa, rodado de duas pastas diferentes:

$ cd escola
$ python3 onde.py
Estou rodando na pasta: /home/ana/escola
Ana: 9.0
Bruno: 6.5
Carla: 8.5

$ cd ..
$ python3 escola/onde.py
Estou rodando na pasta: /home/ana
Notas do ano passado:
Ana: 7.0

Na primeira vez, o terminal estava em /home/ana/escola, e o Python achou as notas deste ano. Na segunda, a Ana voltou para /home/ana (o cd .. sobe uma pasta) e rodou o programa de lá: o Python procurou notas.txt em /home/ana e leu, sem erro nenhum, as notas do ano passado. É o pior tipo de problema: o programa "funciona", com os dados errados. E se o arquivo velho não existisse:

$ mv notas.txt notas-2025.txt                    « a Ana renomeou o arquivo velho
$ python3 escola/onde.py
Estou rodando na pasta: /home/ana
Traceback (most recent call last):
  File "/home/ana/escola/onde.py", line 4, in <module>
    with open("notas.txt", encoding="utf-8") as arquivo:
         ~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
FileNotFoundError: [Errno 2] No such file or directory: 'notas.txt'

O arquivo existe, ao lado do programa, e mesmo assim deu FileNotFoundError: o Python procurou na pasta atual (/home/ana), e não na do programa. Quando um arquivo "que está lá" não é encontrado, desconfie primeiro da pasta atual.

Os tipos de caminho

CaminhoTipoOnde o Python procura
"notas.txt"RelativoNa pasta atual
"escola/notas.txt"RelativoNa pasta escola, dentro da pasta atual
"../notas.txt"RelativoNa pasta de cima da atual (.. = "a pasta mãe")
"/home/ana/escola/notas.txt"AbsolutoExatamente ali, de onde quer que você rode. Começa com / no Linux e no macOS
r"C:\Users\ana\notas.txt"Absoluto (Windows)Exatamente ali, no Windows. Começa com a letra do disco
A barra invertida do Windows

No Windows, as pastas se separam com \, mas dentro de um texto do Python a \ começa os caracteres especiais (\n é a quebra de linha, \t a tabulação; veja Caracteres de Escape). Num caminho como "C:\Users\ana\novo.txt", o \n de \novo vira uma quebra de linha. Escreva o r antes das aspas (r"C:\Users\ana\novo.txt", um texto "cru", em que a \ é só uma barra) ou use a barra normal, "C:/Users/ana/novo.txt", que o Python também aceita no Windows.

Achar o arquivo ao lado do programa

Para o programa achar o arquivo da pasta dele, de onde quer que seja rodado, monte o caminho a partir do próprio programa. O __file__ é o caminho do arquivo .py que está rodando, e o Path do módulo pathlib sabe pegar a pasta dele (.parent, "a pasta mãe") e juntar o nome com /:

from pathlib import Path

pasta_do_programa = Path(__file__).parent
caminho = pasta_do_programa / "notas.txt"
with open(caminho, encoding="utf-8") as arquivo:
    print(arquivo.read())
$ python3 escola/onde_fixo.py
Ana: 9.0
Bruno: 6.5
Carla: 8.5

Rodado de /home/ana, achou as notas certas, de escola. O pathlib tem aula própria: Pastas e Caminhos (pathlib).

No editor do guia

Nas caixas "Experimente", o programa é o /home/ana/main.py e roda na pasta /home/ana, e as abas (como a compras.txt da missão da seção 2) ficam nessa mesma pasta. Por isso, lá, o nome sozinho ("compras.txt") sempre funciona. Os arquivos que o programa cria somem no próximo Rodar.


Quando dá errado

Usar o arquivo depois do with
with open("notas.txt", encoding="utf-8") as arquivo:
    print("Abri o arquivo.")
print(arquivo.read())
$ python3 fechado.py
Abri o arquivo.
Traceback (most recent call last):
  File "/home/ana/fechado.py", line 3, in <module>
    print(arquivo.read())
          ~~~~~~~~~~~~^^
ValueError: I/O operation on closed file.

"Operação de entrada/saída (I/O) num arquivo fechado." O read() da linha 3 está fora do bloco do with (na margem esquerda), e o arquivo já tinha sido fechado. Como consertar: indente a leitura para dentro do bloco, ou guarde o conteúdo numa variável lá dentro e use a variável fora, como no com_with.py.

Escrever num arquivo aberto para ler
with open("notas.txt", encoding="utf-8") as arquivo:
    arquivo.write("Davi: 7.0\n")
$ python3 modo_r_escreve.py
Traceback (most recent call last):
  File "/home/ana/modo_r_escreve.py", line 2, in <module>
    arquivo.write("Davi: 7.0\n")
    ~~~~~~~~~~~~~^^^^^^^^^^^^^^^
io.UnsupportedOperation: not writable

"Operação não suportada: não dá para escrever." Sem modo, o open() abre para ler ("r"). O io. antes do nome diz que esse tipo de erro mora no módulo io, o de entrada e saída. Como consertar: para acrescentar o Davi no fim, open("notas.txt", "a", encoding="utf-8").

Um modo que não existe
with open("notas.txt", "l", encoding="utf-8") as arquivo:
    print(arquivo.read())
$ python3 modo_errado.py
Traceback (most recent call last):
  File "/home/ana/modo_errado.py", line 1, in <module>
    with open("notas.txt", "l", encoding="utf-8") as arquivo:
         ~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
ValueError: invalid mode: 'l'

"Modo inválido: 'l'." Quem pensa em "ler" escreve "l", mas os modos são as letras das palavras em inglês: "r", "w", "a", "x".

Abrir uma pasta
with open("Documentos", encoding="utf-8") as arquivo:
    print(arquivo.read())
$ python3 pasta.py
Traceback (most recent call last):
  File "/home/ana/pasta.py", line 1, in <module>
    with open("Documentos", encoding="utf-8") as arquivo:
         ~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
IsADirectoryError: [Errno 21] Is a directory: 'Documentos'

"É um diretório." Documentos é uma pasta, e o open() abre só arquivos. Como consertar: diga o arquivo dentro da pasta, "Documentos/notas.txt". Para listar o que tem numa pasta, veja pathlib.

Acentos estragados ou UnicodeDecodeError

Você viu na seção 3: pão no lugar de pão quer dizer que um arquivo UTF-8 foi lido com outra codificação; UnicodeDecodeError: 'utf-8' codec can't decode byte… quer dizer que um arquivo de outra codificação foi lido como UTF-8. Como evitar: grave e leia sempre com encoding="utf-8"; para arquivos antigos do Windows, tente encoding="cp1252".


Referência rápida

EscritaO que faz
with open("a.txt", encoding="utf-8") as arquivo:Abre para ler e fecha sozinho no fim do bloco
open("a.txt", "w", encoding="utf-8")Abre para escrever do zero (apaga o que havia)
open("a.txt", "a", encoding="utf-8")Abre para acrescentar no fim
open("a.txt", "x", encoding="utf-8")Cria um arquivo novo; erro se já existir
arquivo.read()Lê tudo, como um texto
arquivo.close()Fecha (desnecessário com with)
arquivo.closedTrue se o arquivo está fechado
os.getcwd()A pasta atual, onde os caminhos relativos são procurados
Path(__file__).parent / "a.txt"O arquivo ao lado do programa
ErroCausa provável
FileNotFoundError: [Errno 2] No such file or directoryNome errado, ou o arquivo está em outra pasta (confira a pasta atual)
FileExistsError: [Errno 17] File existsModo "x" com um arquivo que já existe
IsADirectoryError: [Errno 21] Is a directoryAbriu uma pasta em vez de um arquivo
io.UnsupportedOperation: not writablewrite() num arquivo aberto para ler
ValueError: I/O operation on closed file.Usou o arquivo depois do with ou do close()
ValueError: invalid modeModo que não existe ("l", "e"…)
UnicodeDecodeError / pãoCodificação errada: use encoding="utf-8" (ou a do arquivo)

Exercícios

1. Complete o open

Complete para abrir agenda.txt para ler, com a codificação recomendada:

open("agenda.txt", encoding="") arquivo: print(arquivo.read())

2. Qual modo?

Qual modo acrescenta uma linha no fim de um arquivo, sem apagar o que já está nele? (escreva só a letra)

3. O que acontece ao abrir com "w" um arquivo que já tem conteúdo?

4. Por que preferir with open(…) as arquivo: a open() + close()?

5. notas.txt está em /home/ana/escola, junto com o programa. A Ana roda python3 escola/ler.py estando em /home/ana, e o programa abre "notas.txt". Onde o Python procura?

Missão final: o arquivo que não existe

Missão: o programa pergunta o nome de um arquivo e mostra o conteúdo. A caixa vai "digitar" boletim.txt, que não existe (a única aba é notas.txt). Trate o erro: com um try em volta do with e um except FileNotFoundError:, mostre Não achei o arquivo boletim.txt. (use o nome numa f-string). Para pensar: se a pessoa digitasse notas.txt, o que apareceria?

nome = input("Qual arquivo? ")
with open(nome, encoding="utf-8") as arquivo:
    print(arquivo.read())
Ana: 9.0
Bruno: 6.5
Carla: 8.5
nome = input("Qual arquivo? ")
try:
    with open(nome, encoding="utf-8") as arquivo:
        print(arquivo.read())
except FileNotFoundError:
    print(f"Não achei o arquivo {nome}.")

Resumo

  • open(nome, modo, encoding="utf-8") abre um arquivo e devolve o objeto arquivo; read() lê tudo; close() fecha.
  • Use sempre with open(…) as arquivo:: o arquivo fecha sozinho ao sair do bloco, até se der erro. Depois do bloco, o arquivo não serve mais (I/O operation on closed file).
  • Escreva sempre encoding="utf-8": sem ele, o Python usa o padrão do sistema, que no Windows (até o 3.14) costuma ser cp1252, e os acentos viram ã.
  • Modos: "r" ler (o padrão), "w" escrever do zero (apaga), "a" acrescentar no fim, "x" criar sem apagar (FileExistsError se já existe).
  • FileNotFoundError: confira o nome e a pasta; quando o nome vem do usuário, trate com try/except FileNotFoundError.
  • Um caminho relativo ("notas.txt") é procurado na pasta atual, de onde você rodou o programa, e não na pasta do programa. Para achar o arquivo ao lado do programa: Path(__file__).parent / "notas.txt".