Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

You don't even need the locals() function to get into trouble:

    x = [1, 2, 3, 4]
    def foo():
        x[0] += 3  # Okay
    def bar():
        x += [3]   # UnboundLocalError
    def qux():
        x = [5, 6, 7, 8]  # Binds a new `x`.


    def bar():
        x += [3]   # UnboundLocalError
This is an especially funky one. x.extend([3]) would be allowed. Presumably x += [3] is not because it expands to x = x + [3]... However, the += operator on lists works the same as extend(), i.e. it changes the list in-place.


dis.dis(bar) shows:

              0 LOAD_FAST                0 (x)
              2 LOAD_CONST               1 (3)
              4 INPLACE_ADD
              6 STORE_FAST               0 (x)
              8 LOAD_CONST               0 (None)
             10 RETURN_VALUE
So INPLACE_ADD and STORE_FAST are essentially doing x = x.__iadd__([3])




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: