Reputation: 153
I encountered a code which looks similar to this:
from contextlib import contextmanager, ContextDecorator
class makepara(ContextDecorator):
def __enter__(self):
print ("<p>")
return self
def __exit__(self, *args):
print ("</p>")
return False
@makepara()
def emit_data():
print (" here is HTML code")
emit_data()
I found related answer this but when i change the above code to
from contextlib import contextmanager, ContextDecorator
class makepara(ContextDecorator):
def __enter__(self):
print ("<p>")
def __exit__(self, *args):
print ("</p>")
@makepara()
def emit_data():
print (" here is HTML code")
emit_data()
there is no change in the output, that makes me wonder what does return self
actually does and how to be used?
Upvotes: 1
Views: 438
Reputation: 20224
return self
is not only useful in with
statement, but also useful in many other situations.
For example, when you open a file using:
with open("file") as f:
....
Function open
actually return an object which implements __enter__
, and in its __enter__
, it use return self
to let you bind this instance to variable f
, so that you can do f.read
or something else after.
In other situations, for another example, if you want to chained call(Maybe data = a.connect().get("key").to_dict()
). You need to add return self
to connect
and get
.
But after all, return self
is nothing more than returning a normal variable.
Upvotes: 2
Reputation: 363053
You choose to return self
(or some other object, but usually the context manager instance itself
) so that a name can be bound with this syntax:
with makepara() as var:
...
The object returned by __enter__
will be bound to the name var
within the context (and will, in fact, remain bound to var
after exiting context).
If you wouldn't need any value bound after entering context, it is possible to omit an explicit return (the implicit return of None
would be used in this case regardless) but there is no harm and no disadvantage in returning self
anyway.
Upvotes: 4