How to use methods of an object within "with" in Python?

Asked

Viewed 85 times

2

Hello, I am studying a little more about the best practices of using Python and I came across a command that I do not know very well, the with, so I decided to study a little bit better about how it works, and I’m trying to take a test, the program I wrote is the following:

class Teste(object):
def __init__(self, var1):
    self.var1 = var1
def __enter__(self):
    print('Entrou!!')
def __exit__ (self, exception, value, traceback):
    print('Saiu!!')
def mostrar_var(self):
    print('A variavel é: {}'.format(self.var1))


if __name__ == '__main__':
    with Teste('Olá') as objeto_teste:
        objeto_teste.mostrar_var()

My intention in this test is to start the Test object, run the "mostrar_var" method and close the object, but I am not able to execute the "mostrar_var" method, just start and end the object. I would like a help to better understand what I am doing wrong and how these methods can be accessed using the with. The Exception I get running this code is as follows:

Entrou!! Saiu!! Traceback (most recent call last):   File "C:\Users\ZanattaJ\Desktop\teste.py", line 14, in <module>
    objeto_teste.mostrar_var() AttributeError: 'NoneType' object has no attribute 'mostrar_var'
  • Related or duplicate: https://answall.com/q/49238/101

2 answers

2

In Python "with" is a context manager created to manage "Unmanaged-Resources", more details context-manager and Unmanaged-Resources. In short, the use of context managers is widely used, and should be for the sake of good server memory management, since there are resources that are not managed by the AG - Garbage Collect.

Example

class FileManager(): 
    def __init__(self, filename, mode): 
        self.filename = filename 
        self.mode = mode 
        self.file = None

    def __enter__(self): 
        self.file = open(self.filename, self.mode) 
        return self.file

    def __exit__(self, exc_type, exc_value, exc_traceback): 
        self.file.close() 

# loading a file  
with FileManager('test.txt', 'w') as f: 
    f.write('Test') 

print(f.closed)  

Note of a practical case

Imagine that you want to access resources such as log files, which can grow exponentially and can reach several hundred MB in size or even GB’s, if for some reason there is a tool that opens this file to load all errors and if you do not use a context manager you can 'paste' your server due to lack of memory when opening the file several times if the resource is not released from memory.

2


When you do something like:

with Teste('Olá') as objeto_teste:
    objeto_teste.mostrar_var()

The value of objeto_teste shall be defined from the return of the method __enter__. As your method has no return, None will be assigned, so the error.

As you want to work directly on the generated instance within the context manager, you can return self in this method:

def __enter__(self):
    print('Entrou!!')
    return self

This way, when executing, the output will be:

Entrou!!
A variavel é: Olá
Saiu!!

For more details on with, read What’s with no Python for?

  • Thank you very much for the answer, I had already given a read on this other question but had not understood, I will read more carefully now, but for now your responsta has already been of great help to understand what I was doing wrong,

Browser other questions tagged

You are not signed in. Login or sign up in order to post.