Object becomes None when using a context manager
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
.
The function you've defined between 'with' and 'as' must have and only have one return value. 'with' will pass the value to its built-in method __enter__()
.
A class-type object in Python will not return any value if not defined when you called it.
Similarly, if you called a class-type object with its method that returns nothing, it will also throw out exception.
You can't write like this:
with open('file.txt').readlines() as lines:
This generated two return values, and it's even not allowed to pass to one variable in Python.
But this is good to use:
with open('file.txt') as f:
lines = f.readlines()