Skip to content Skip to sidebar Skip to footer

Received "unboundlocalerror: Local Variable 'e' Referenced Before Assignment" When The Variable Was Initialized

[Community edit to give reproducible example:] def main(): e = None print(locals()) while not e: try: raise Exception except Exception as e:

Solution 1:

This error is caused by the new try...except... scope, which is a Python 3 feature. See PEP-3110

In Python 3, the following block

try:
    try_body
except E as N:
    except_body
...

gets translated to (in Python 2.5 terms)

try:
    try_body
except E, N:
    try:
        except_body
    finally:
        N = Nonedel N
...

Therefore, this function in Python 3

defmain():
    e = Noneprint(locals())
    whilenot e:
        try:
            raise Exception
        except Exception as e:
            pass

is equivalent to

defmain():
    e = Noneprint(locals())
    ifnot e:
        try:
            raise Exception
        except Exception as e:
            passdel e
    ifnot e:
        try:
            raise Exception
        except Exception as e:
            passdel e
    ...

e was initialized, but it has been deleted after the first try except block. Thus, UnboundLocalError is inevitbale.

Solution 2:

Well, I don't know what's causing the actual problem, but why don't you just use break when an exception occurs? Your loop becomes:

whileTrue:
    try:
        score = pickle.load(score_list)
        name = pickle.load(score_list)
        score_name.append([score, name])
    except EOFError as e:
        break

As far as I know, this is the idiomatic way of achieving "run loop while there's no exception"

Edit: Why this happens

It would seem that in python3, once you exit the scope of an exception handler, the variable that the exception was bound to is removed from the namespace. I modified the code to the following:

defmain():
    e = Noneprint(locals())
    whilenot e:
        try:
            raise Exception
        except Exception as e:
            passprint(locals())

main()

Output:

{'e': None}
{}
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 4, in main
UnboundLocalError: local variable 'e' referenced before assignment

This is not the case in python2. Given that the syntax was changed for how you assign an exception to a variable, I'm not surprised that the semantics of it were changed as well. Although I do think that this is "surprising" behaviour(in the sense that it is not what you would expect).

In any case, the proper way to exit a loop when an exception occurs is in the code above. If you want to keep the exception outside of the exception handler's scope I guess you could still do something like this:

defmain():
   e = Noneprint(locals())
   whilenot e:
      try:
         raise Exception
      except Exception as ex:
         e = ex
      print(locals())

main()

Which produces the following output:

{'e': None}
{'e': Exception()}

But you really shouldn't be doing that for your particular use-case.

Post a Comment for "Received "unboundlocalerror: Local Variable 'e' Referenced Before Assignment" When The Variable Was Initialized"