variable scope in try ... EXCEPT block.

Ben Bacarisse ben.usenet at bsb.me.uk
Thu Jul 12 05:45:36 EDT 2018


aleiphoenix <aleiphoenix at gmail.com> writes:

> suppose following code running with Python-3.4.8 and Python-3.6.5
>
>
> # -*- coding: utf-8 -*-
>
>
> def hello():
>     err = None
>     print('0: {}'.format(locals()))
>     try:
>         b = 2
>         print('1: {}'.format(locals()))
>         raise ValueError()
>         print('2: {}'.format(locals()))
>     except ValueError as err:
>         print('3: {}'.format(locals()))
>         pass
>     print('4: {}'.format(locals()))
>     return '', err
>
>
> hello()
>
>
>
> got output:
>
> 0: {'err': None}
> 1: {'err': None, 'b': 2}
> 3: {'err': ValueError(), 'b': 2}
> 4: {'b': 2}
> Traceback (most recent call last):
>   File "err.py", line 19, in <module>
>     hello()
>   File "err.py", line 16, in hello
>     return '', err
> UnboundLocalError: local variable 'err' referenced before assignment
>
>
> But without this UnboundLocalError with Python-2.7.14
>
>
> My question is, does except ... as ... create a new scope from outer
> block, causing 'err' be hidden from outer scope? Is this intentional?

Yes, it's intentional, but it's not exactly a scope.  In

  https://docs.python.org/3/reference/compound_stmts.html#try

you will find:

  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.

This appears to be a change from Python 2.  That wording is not present
in

  https://docs.python.org/2/reference/compound_stmts.html#try

-- 
Ben.


More information about the Python-list mailing list