4.1 Fechamento de arquivos e tratamento de erros
Às vezes, erros ou exceções surgem ao ler um arquivo, e ele fica
aberto. Isso pode levar a um vazamento de memória ou de
file handlers
. Por isso, precisamos envolver a manipulação de arquivos em um
bloco try-except
.
Suponha que você tem o seguinte código:
file = open('example.txt', 'a') # Abrindo o arquivo
file.write("This is a new line added to the file.")
file.close() # Fechando o arquivo
É necessário envolvê-lo no bloco try-except
:
try:
file = open('example.txt', 'a') # Abrindo o arquivo
file.write("This is a new line added to the file.")
file.close() # Fechando o arquivo
except FileNotFoundError:
print("File not found")
file.close() # Fechando o arquivo
Para não repetir o método close()
duas vezes, podemos colocá-lo no bloco
finally
:
try:
file = open('example.txt', 'a') # Abrindo o arquivo
file.write("This is a new line added to the file.")
except FileNotFoundError:
print("File not found")
finally:
file.close() # Fechando o arquivo
Esse código parece bonito, mas... não funciona, já que a variável file
é definida apenas no bloco try
e não está acessível nos blocos except
e finally
.
Portanto, precisamos definir a variável num nível acima:
file = None
try:
file = open('example.txt', 'a') # Abrindo o arquivo
file.write("This is a new line added to the file.")
except FileNotFoundError:
print("File not found")
finally:
file.close() # Fechando o arquivo
Essa solução é melhor, mas ainda tem suas falhas. Por exemplo, se o arquivo
não for aberto, a variável file
ainda será None
. E então,
tentar fechar o arquivo resultará em um erro — você estará tentando chamar
o método close()
em um objeto inexistente.
Portanto, precisamos adicionar uma verificação antes de chamar o método close()
:
file = None
try:
file = open('example.txt', 'a') # Abrindo o arquivo
file.write("This is a new line added to the file.")
except FileNotFoundError:
print("File not found")
finally:
if file:
file.close() # Fechando o arquivo
Se você está surpreso que 3 linhas de código viraram 9, você não está sozinho. Felizmente, já existe uma solução pronta para esse problema, que abordaremos a seguir.
4.2 Operador with
O operador with
no Python oferece uma forma conveniente de gerenciar
recursos, como arquivos, garantindo que eles sejam fechados automaticamente
após o término do bloco with
. Isso simplifica o código e evita vazamentos
de recursos, como arquivos não fechados.
Sintaxe geral do operador with
:
with expressão as variável:
manipulação da variável
O operador with
é usado para
envolver a execução de um bloco de código com um gerenciador de contexto. Quando
usamos o operador with
, o Python chama automaticamente os métodos
__enter__()
e
__exit__()
do objeto gerenciador de contexto, facilitando
o gerenciamento de recursos.
Exemplo de uso do with
ao trabalhar com arquivos:
with open('example.txt', 'w') as file:
file.write("Hello, World!\n")
file.write("This is a test file.\n")
Nesse exemplo, o arquivo example.txt
é aberto no modo de escrita, e o nome
do arquivo é associado à variável file
. O bloco de código
dentro do with
fecha automaticamente o arquivo após executar todas as operações de escrita.
4.3 Fechamento automático de arquivo
Uma das principais vantagens de usar
o operador with
é o fechamento
automático do arquivo após o término do bloco de código. Isso ocorre
mesmo que uma exceção seja levantada, tornando
o código mais seguro e confiável.
Exemplo de fechamento automático de arquivo:
try:
with open('example.txt', 'w') as file:
file.write("Hello, World!\n")
file.write("This is a test file.\n")
# Exceção para verificar se o arquivo ainda será fechado
raise Exception("Something went wrong")
except Exception as e:
print(f"Caught an exception: {e}")
# Neste ponto, o arquivo já está fechado
Sempre use o operador with
ao
trabalhar com arquivos. É simples e ajuda a evitar muitos erros.
4.4 Nos bastidores do operador with
O funcionamento do operador with
é baseado nos métodos __enter__()
e
__exit__()
, que devem ser implementados em uma classe usada
como gerenciador de contexto.
Para que um objeto possa ser usado com
o operador with
, ele deve implementar os métodos __enter__()
e
__exit__()
. Esses métodos definem o comportamento na entrada e
saída do contexto.
Método __enter__()
O método __enter__()
é chamado na entrada do bloco with
.
Ele realiza a inicialização do recurso e retorna o objeto que
será associado à variável especificada após as
.
Método __exit__()
O método __exit__()
é chamado ao sair do bloco with
. Ele realiza
ações de finalização, como liberação de recursos ou fechamento
de arquivos. O método recebe três argumentos: exc_type
, exc_val
e exc_tb
,
que contêm informações sobre a exceção, se ocorreu.
-
exc_type
: tipo da exceção (por exemplo,ZeroDivisionError
). -
exc_val
: valor da exceção (por exemplo, mensagem de erro). exc_tb
: rastreamento da pilha da exceção.
Se o método __exit__()
retornar True
,
a exceção será suprimida. Se retornar
False
, a exceção será relançada.
Exemplo:
class MyContextManager:
def __enter__(self):
print("Entering the context")
return self
def __exit__(self, exc_type, exc_val, exc_tb):
if exc_type:
print(f"An exception occurred: {exc_type}, {exc_val}")
return False # A exceção não é suprimida
with MyContextManager() as manager:
print("Inside the with block")
GO TO FULL VERSION