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-blockThe
expressionhere 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 namevariableif the optional as clause is present.Note that the
variableis not necessarily assigned the result of theexpression; the result of theexpressionis the object that supports the context protocol, and thevariablemay 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
asclause ofwithstatements 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