Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

141
Views
What is the scope of the `as` binding in an `except` statement or context manager?

I know that in general python only makes new scopes for classes, functions etc., but I'm confused by the as statement in a try/except block or context manager. Variables assigned inside the block are accessible outside it, which makes sense, but the variable bound with as itself is not.

So this fails:

try:
    raise RuntimeError()
except RuntimeError as error:
    pass

print(repr(error))

but this succeeds:

try:
    raise RuntimeError()
except RuntimeError as e:
    error = e

print(repr(error))

What's going on with the variable bound with as, and why don't normal python scoping rules apply? The PEP indicates that it's just a normally bound python variable, but that doesn't seem to be the case.

over 4 years ago · Santiago Trujillo
2 answers
Answer question

0

This is a documented exception to the normal rules that *specifically applies to try-except statements, from the language reference:

When an exception has been assigned using as target, it is cleared at the end of the except clause. This is as if:

except E as N:
    foo

was translated to

except E as N:
    try:
        foo
    finally:
        del N

This means the exception must be assigned to a different name to be able to refer to it after the except clause. Exceptions are cleared because with the traceback attached to them, they form a reference cycle with the stack frame, keeping all locals in that frame alive until the next garbage collection occurs.

As noted, the reason this occurs to prevent reference cycles.

Note, this only applies to a try - except compound statement, as is not an independent statement, it is a part of different, independent compound statements (with and try-except)

over 4 years ago · Santiago Trujillo Report

0

As explained in PEP 3110, as well as current documentation, variables bound with as in an except block are explicitly and specially cleared at the end of the block, even though they share the same local scope. This improves the immediacy of garbage collection. The as syntax was originally not available for exceptions in 2.x; it was backported for 2.6, but the old semantics were preserved.

The same does not apply to with blocks:

>>> from contextlib import contextmanager
>>> @contextmanager
... def test():
...     yield
... 
>>> with test() as a:
...     pass
... 
>>> a # contains None; does not raise NameError
>>> 
>>> def func(): # similarly within a function
...     with test() as a:
...         pass
...     return a
... 
>>> func()
>>> 

The behaviour is specific to the except block, not to the as keyword.

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!