I am trying to run this code:
class A:
def __enter__(self):
print "enter"
def __exit__(self, *args):
print "exit"
def __init__(self, i):
self.i = i
with A(10) as a:
print a.i
And I get this error:
enter
exit
Traceback (most recent call last):
File ".last_tmp.py", line 9, in <module>
print a.i
AttributeError: 'NoneType' object has no attribute 'i'
What is wrong with my syntax?
You will need to return self
from __enter__
:
def __enter__(self):
print "enter"
return self
Your with
statement is effectively equivalent to:
a = A(10).__enter__() # with A(10) as a:
try:
print a.i # Your with body
except:
a.__exit__(exception and type)
raise
else:
a.__exit__(None, None, None)
So, you need to return something, otherwise a
will have the value of None
(default return value), and None
does not have an attribute named i
, so you get an AttributeError
.
The return value of the object's __enter__
method is what is assigned to the name following the as
keyword. Your method (implicitly) returns None
, resulting in the error you see. Instead, __enter__
should return self
, so that the object created by A(10)
is assigned to a
.
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