UnboundLocalError when manipulating variables yields inconsistent behavior

后端 未结 3 1979
别跟我提以往
别跟我提以往 2021-01-23 03:27

In Python, the following code works:

a = 1
b = 2

def test():
    print a, b

test()

And the following code works:

a = 1
b = 2
         


        
3条回答
  •  清歌不尽
    2021-01-23 04:22

    When you modify a, it becomes a local variable. When you're simply referencing it, it is a global. You haven't defined a in the local scope, so you can't modify it.

    If you want to modify a global, you need to call it global in your local scope.

    Take a look at the bytecode for the following

    import dis
    
    a = 9 # Global
    
    def foo():
        print a # Still global
    
    def bar():
        a += 1 # This "a" is local
    
    
    dis.dis(foo)
    

    Output:

      2           0 LOAD_GLOBAL              0 (a)
                  3 PRINT_ITEM
                  4 PRINT_NEWLINE
                  5 LOAD_CONST               0 (None)
                  8 RETURN_VALUE
    

    For the second function:

    dis.dis(bar)
    

    Output:

      2           0 LOAD_FAST                0 (a)
                  3 LOAD_CONST               1 (1)
                  6 INPLACE_ADD
                  7 STORE_FAST               0 (a)
                 10 LOAD_CONST               0 (None)
                 13 RETURN_VALUE
    

    The first function's bytecode loads the global a (LOAD_GLOBAL) because it is only being referenced. The second function's bytecode (LOAD_FAST) tries to load a local a but one hasn't been defined.

    The only reason your second function works is because a is equal to 1. If a was anything but 1, the local assignment to b wouldn't happen and you'd receive the same error.

提交回复
热议问题