Python local vs global variables

前端 未结 4 1691
无人共我
无人共我 2020-12-01 21:52

I understand the concept of local and global variables in Python, but I just have a question about why the error comes out the way it is in the following code. Python execut

4条回答
  •  囚心锁ツ
    2020-12-01 22:05

    Setup and Testing

    To analyze your question, let's create two separate test functions that replicate your issue:

    a=0
    
    def test1():
        print(a)
    
    test1()
    

    prints 0. So, calling this function is not problematic, but on the next function:

    def test2():
        print(a)  # Error : local variable 'a' referenced before assignment
        a=0  
    
    test2()
    

    We get an error:

    Traceback (most recent call last):
      File "", line 1, in 
      File "", line 2, in test2
    UnboundLocalError: local variable 'a' referenced before assignment
    

    Disassembly

    We can disassemble the two functions (first Python 2):

    >>> import dis
    >>> dis.dis(test1)
      2           0 LOAD_GLOBAL              0 (a)
                  3 PRINT_ITEM          
                  4 PRINT_NEWLINE       
                  5 LOAD_CONST               0 (None)
                  8 RETURN_VALUE        
    

    And we see that the first function automatically loads the global a, while the second function:

    >>> dis.dis(test2)
      2           0 LOAD_FAST                0 (a)
                  3 PRINT_ITEM          
                  4 PRINT_NEWLINE       
    
      3           5 LOAD_CONST               1 (0)
                  8 STORE_FAST               0 (a)
                 11 LOAD_CONST               0 (None)
                 14 RETURN_VALUE      
    

    seeing that a is assigned inside it, attempts to LOAD_FAST from the locals (as a matter of optimization, as functions are pre-compiled into byte-code before running.)

    If we run this in Python 3, we see nearly the same effect:

    >>> test2()
    Traceback (most recent call last):
      File "", line 1, in 
      File "", line 2, in test2
    UnboundLocalError: local variable 'a' referenced before assignment
    >>> 
    >>> import dis
    >>> dis.dis(test1)
      2           0 LOAD_GLOBAL              0 (print) 
                  3 LOAD_GLOBAL              1 (a) 
                  6 CALL_FUNCTION            1 (1 positional, 0 keyword pair) 
                  9 POP_TOP              
                 10 LOAD_CONST               0 (None) 
                 13 RETURN_VALUE     
    
    >>> dis.dis() # disassembles the last stack trace
      2           0 LOAD_GLOBAL              0 (print) 
        -->       3 LOAD_FAST                0 (a) 
                  6 CALL_FUNCTION            1 (1 positional, 0 keyword pair) 
                  9 POP_TOP              
    
      3          10 LOAD_CONST               1 (0) 
                 13 STORE_FAST               0 (a) 
                 16 LOAD_CONST               0 (None) 
                 19 RETURN_VALUE        
    

    We see our error is on the LOAD_FAST again.

提交回复
热议问题