How to prove that parameter evaluation is “left to right” in Python?

后端 未结 6 2106
梦毁少年i
梦毁少年i 2020-12-19 04:45

For example, in JavaScript we could write a program like this:

var a = 1;
testFunction(++a, ++a, a);
function testFunc         


        
6条回答
  •  既然无缘
    2020-12-19 05:24

    Using Python 3:

    >>> a = []
    >>> f = print(
        a.append(1), a[:],
        a.append(2), a[:],
        a.append(3), a[:]
    )
    None [1] None [1, 2] None [1, 2, 3]
    

    Archive:

    >>> a = []
    >>> f = print(a.append(1), a, a.append(2), a, a.append(3), a)
    

    Curiously enough (at first), this code produces:

    None [1, 2, 3] None [1, 2, 3] None [1, 2, 3]
    

    However, dis(f) makes this clearer:

    >>> dis(f)
    
      1           0 LOAD_NAME                0 (print) #Loads the value of 'print' into memory. Precisely, the value is pushed to the TOS (Top of Stack)
        -->       3 LOAD_NAME                1 (a) #Loads the value of object 'a' 
                  6 LOAD_ATTR                2 (append) #Loads the append attribute (in this case method)
                  9 LOAD_CONST               0 (1) #Loads the constant 1
                 12 CALL_FUNCTION            1 #a.append(1) is called
                 15 LOAD_NAME                1 (a) #for print(...,a,...)
                 18 LOAD_NAME                1 (a) #for the next a.append()
                 21 LOAD_ATTR                2 (append) 
                 24 LOAD_CONST               1 (2) 
                 27 CALL_FUNCTION            1 #a.append(2)
                 30 LOAD_NAME                1 (a) 
                 33 LOAD_NAME                1 (a) 
                 36 LOAD_ATTR                2 (append) 
                 39 LOAD_CONST               2 (3) 
                 42 CALL_FUNCTION            1 #a.append(3)
                 45 LOAD_NAME                1 (a) #loads a to be used thrice by print
                 48 CALL_FUNCTION            6 #calls print
                 51 PRINT_EXPR                 #prints TOS and clears it
                 52 LOAD_CONST               3 (None) #Loads None
                 55 RETURN_VALUE             #Returns None
    

    The output of dis(f) is what we expected - L-to-R evaluation. Essentially, this "discrepancy" is a consequence of print() being evaluated last. By then, the value of a has changed to [1, 2, 3] and the same final object is printed thrice.

    If we replace a with a[:], we get the expected result.

提交回复
热议问题