Reputation: 19
Hey guys am new to python development and i tried to undrstand the use of with
..The code i have wrote is
class Mgr(object):
def __enter__(self): pass
def __exit__(self, ext, exv, trb):
if ext is not None: print "no not possible"
print "OK I caught you"
return True
def honey(self):
print 'guli'
b = Mgr()
with b.honey() as d:
print d
When i run the code it gaves me output guli
along with an attribute error.
I know with works with context managers and is b.honey()
a context manager ??.. Can you guys please explain me why this error occurs ..Thanx for the help..
Traceback (most recent call last):
File "C:/Python27/c", line 18, in <module>
with b.honey() as d:
AttributeError: __exit__
Upvotes: 1
Views: 642
Reputation: 365895
The problem is that, while b
is a context mananger, b.honey()
isn't.
b.honey()
is just whatever you return from the honey
method. In this case, you don't return anything, so it's None
.
If you want b.honey()
to return b
, you could—just add return self
to the end of the method. But this is kind of strange. You wouldn't normally expect using b.honey()
in a with
statement to "close" b
. That would be like with f.read(8192) as buf:
closing the file f
. (There are some use cases where that might make sense, but not in general.)
Or, there's no reason b
and b.honey()
can't both be totally separate context managers. It's hard to think of a case where you'd want this, but if you did, you could return an instance of some other class—or use the contextmanager
decorator:
@contextlib.contextmanager
def honey(self):
print 'guli'
yield 'this is d'
print 'ilug'
But more likely, what you actually wanted is something like this:
with Mgr() as d:
d.honey()
print d
But in that case, you probably want to change the __enter__
method to return self
. Whatever it returns is what's going to end up in d
.
So, for example:
class Mgr(object):
def __enter__(self):
return self
def __exit__(self, ext, exv, trb):
if ext is not None: print "no not possible"
print "OK I caught you"
return True
def honey(self):
print 'guli'
with Mgr() as d:
d.honey()
print d
Now, the with Mgr() as d
constructs and initializes an Mgr
instance (you don't have an __init__
, so that does nothing), then calls its __enter__
method, which returns that instance, then assigns the result to d
. Then it runs d.honey()
and print d
. And then (whether there was an exception or not) it calls d.__exit__(…)
.
Upvotes: 2