Skip to content
Advertisement

Invoking a constructor in a ‘with’ statement

I have the following code:

JavaScript

Running it produces the following output:

JavaScript

But I expected it to produce:

JavaScript

Why isn’t the code within my first example called?

Advertisement

Answer

The __enter__ method should return the context object. with ... as ... uses the return value of __enter__ to determine what object to give you. Since your __enter__ returns nothing, it implicitly returns None, so test is None.

JavaScript

So test is none. Then test.name is an error. That error gets raised, so Test('first').__exit__ gets called. __exit__ returns True, which indicates that the error has been handled (essentially, that your __exit__ is acting like an except block), so the code continues after the first with block, since you told Python everything was fine.

Consider

JavaScript

You might also consider not returning True from __exit__ unless you truly intend to unconditionally suppress all errors in the block (and fully understand the consequences of suppressing other programmers’ errors, as well as KeyboardInterrupt, StopIteration, and various system signals)

User contributions licensed under: CC BY-SA
7 People found this is helpful
Advertisement