Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Object becomes None when using a context manager

Tags:

Why doesn`t this work:

class X:     var1 = 1     def __enter__(self): pass     def __exit__(self, type, value, traceback): pass  with X() as z:     print z.var1 

I get:

print z.var1 AttributeError: 'NoneType' object has no attribute 'var1' 
like image 569
Weholt Avatar asked Feb 23 '11 16:02

Weholt


People also ask

What actions are guaranteed by a context manager?

A context manager usually takes care of setting up some resource, e.g. opening a connection, and automatically handles the clean up when we are done with it. Probably, the most common use case is opening a file. The code above will open the file and will keep it open until we are out of the with statement.

How does context manager work?

Context managers allow you to allocate and release resources precisely when you want to. The most widely used example of context managers is the with statement. Suppose you have two related operations which you'd like to execute as a pair, with a block of code in between.

What does __ enter __ do in Python?

__enter__() is provided which returns self while object. __exit__() is an abstract method which by default returns None . See also the definition of Context Manager Types. New in version 3.6.

What does __ exit __ do in Python?

The __exit__ method takes care of releasing the resources occupied with the current code snippet. This method must be executed no matter what after we are done with the resources.


2 Answers

Change the definition of X to

class X(object):     var1 = 1     def __enter__(self):         return self     def __exit__(self, type, value, traceback):         pass 

with assigns the return value of the __enter__() method to the name after as. Your __enter__() returned None, which was assigned to z.

I also changed the class to a new-style class (which is not critical to make it work).

like image 86
Sven Marnach Avatar answered Sep 21 '22 22:09

Sven Marnach


See the docs for context managers:

__enter__( ) Enter the runtime context and return either this object or another object related to the runtime context. The value returned by this method is bound to the identifier in the as clause of with statements using this context manager. An example of a context manager that returns itself is a file object. File objects return themselves from __enter__() to allow open() to be used as the context expression in a with statement.

An example of a context manager that returns a related object is the one returned by decimal.Context.get_manager(). These managers set the active decimal context to a copy of the original decimal context and then return the copy. This allows changes to be made to the current decimal context in the body of the with statement without affecting code outside the with statement.

Your __enter__ method doesn't return anything, which is the same as returning None.

like image 23
bgporter Avatar answered Sep 20 '22 22:09

bgporter