Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

should the return value for `__enter__` method always be `self` in python

Tags:

python

Shouldn't the return value for the __enter__ method be self always.

Python documentation says :

object.__enter__(self) Enter the runtime context related to this object. The with statement will bind this method’s return value to the target(s) specified in the as clause of the statement, if any.

With this, to do anything practical, should't self be returned always from __enter__ method of a class as without it one would not be able to call other class methods on the context.

For example, in the following code, s.main() works fine but b1.main() errors out.

class a(object):
    def __init__(self):
        pass

    def __enter__(self):
        return self

    def __exit__(self ,type, value, traceback):
        return self

    def main(self):
        print " in a::main self %d " , id(self)


class b(object):
    def __init__(self):
        pass

    def __enter__(self):
        return "something else"

    def __exit__(self ,type, value, traceback):
        pass

    def main(self):
        print "in b::main !! self id " , id(self)

with a() as s:
    s.main()

with b() as b1:
    b1.main()

s = a()
s.main()
like image 378
ViFI Avatar asked Jul 09 '16 12:07

ViFI


1 Answers

Not if it makes sense to use an attribute of the instance as the context manager:

class A:
    def __init__(self, useful_obj):
        self.useful_obj = useful_obj

   def __enter__(self):
       return self.useful_obj

   def __exit__(self):
       pass

with A(some_obj) as a:
    # magic done implicitly by a.useful_obj
    .
    .
    .

This situation can be seen in SqlAlchemy's code.

The code sample that you provided would work if you use any of the str methods, for example:

with b() as b1:
    print b1.upper()

>> SOMETHING ELSE
like image 61
DeepSpace Avatar answered Nov 15 '22 04:11

DeepSpace