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'
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.
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.
__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.
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.
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).
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 allowopen()
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
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With