Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is assigned to `variable`, in `with expression as variable`?

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 name variable if the optional as clause is present.

Note that the variable is not necessarily assigned the result of the expression; the result of the expression is the object that supports the context protocol, and the variable 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.

like image 404
Tim Avatar asked Sep 14 '17 17:09

Tim


People also ask

Can an expression be assigned to a variable?

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.

What is variable and expression in Python?

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.


2 Answers

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 of with 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.

like image 171
Dimitris Fasarakis Hilliard Avatar answered Sep 20 '22 05:09

Dimitris Fasarakis Hilliard


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
like image 35
Blender Avatar answered Sep 24 '22 05:09

Blender