Operador with

Python SELF PT
Nível 21 , Lição 3
Disponível

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")
Comentários
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION