python lover
python lover

Reputation: 19

Error using with statement

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

Answers (1)

abarnert
abarnert

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

Related Questions