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