From Learning Python:
The basic format of the with statement looks like this, with an optional part in square brackets here:
with expression [as variable]: with-block
The
expression
here is assumed to return an object that supports the context management protocol (more on this protocol in a moment). This object may also return a value that will be assigned to the namevariable
if the optional as clause is present.Note that the
variable
is not necessarily assigned the result of theexpression
; the result of theexpression
is the object that supports the context protocol, and thevariable
may be assigned something else intended to be used inside the statement.
expression
is evaluated to a context manager object.
What is assigned to variable
? The quote only says that it is not a context manager object.
Does the assignment to variable
call some method of a context manager class to produce the actual value assigned to variable
?
Thanks.
The evaluation of an expression produces a value, which is why expressions can appear on the right hand side of assignment statements. A value all by itself is a simple expression, and so is a variable. Confusingly, evaluating an expression is not quite the same thing as printing a value.
A Python variable is a reserved memory location to store values. In other words, a variable in a python program gives data to the computer for processing. Every value in Python has a datatype. Different data types in Python are Numbers, List, Tuple, Strings, Dictionary, etc.
Whatever is returned from __enter__
. From the documentation on the __enter__
method of context managers:
contextmanager.__enter__()
Enter the runtime context and return either this object or another object related to the runtime context. The value returned by this method is bound to the identifier in the
as
clause ofwith
statements using this context manager.
(Emphasis mine)
The result of calling __enter__
could very well be a context manager, nothing in the specification forbids this. It could of course be another object related to the runtime context, as the docs state.
Objects that return themselves from __enter__
can be used again and again as context managers. file
objects, for example:
with open('test_file') as f1: # file.__enter__ returns self
with f1 as f2: # use it again, get __self__ back
print("Super context managing")
with f2 as f3, f1 as f4: # getting weird.
print("This can go on since f1.__enter__ returns f1")
print("f1.__exit__ has been called here, though :)")
print("f1 closed: {}".format(f1.closed))
Not that the previous made much sense but just to make the point clear.
Your object can function as a context manager if it provides both __enter__
and __exit__
. The object returned by __enter__
is bound to the object you specify in the as
part of the with
statement:
In [1]: class Foo:
...: def __enter__(self):
...: return 'hello'
...: def __exit__(self, *args):
...: pass
...:
In [2]: with Foo() as a:
...: print(a)
...:
hello
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