Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/dart/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 推送到堆栈上的帧的顺序_Python_Compiler Construction_Stack_Vm Implementation - Fatal编程技术网

Python 推送到堆栈上的帧的顺序

Python 推送到堆栈上的帧的顺序,python,compiler-construction,stack,vm-implementation,Python,Compiler Construction,Stack,Vm Implementation,假设您有以下代码 def square(x): print ("Just before square returns") for k in dir(): print ("{0} -------> {1}".format(k, eval(k))) return x*x def cube(x): print ("Just before cube returns") for k in dir(): print ("{0} -

假设您有以下代码

def square(x):
    print ("Just before square returns")
    for k in dir():
        print ("{0} -------> {1}".format(k, eval(k)))
    return x*x
def cube(x):
    print ("Just before cube returns")
    for k in dir():
        print ("{0} -------> {1}".format(k, eval(k)))
    return x*x*x

x = 5
print ("cube(square({0})) = {1}".format(x, cube(square(x))))
print ("Just before main returns")
for k in dir():
    print ("{0} -------> {1}".format(k, eval(k)))
运行此代码将显示以下内容

Just before square returns
x -------> 5
Just before cube returns
x -------> 25
cube(square(5)) = 15625
Just before main returns
__builtins__ -------> <module 'builtins' (built-in)>
__cached__ -------> None
__doc__ -------> None
__file__ -------> exampleOne.py
__name__ -------> __main__
__package__ -------> None
cube -------> <function cube at 0x1037b78>
square -------> <function square at 0x1037af0>
x -------> 5
就在square返回之前
x------>5
就在立方体返回之前
x------>25
立方体(正方形(5))=15625
就在主回归之前
__内置-->
__缓存的----------------->无
__文件------------>无
__文件-->exampleOne.py
__名称----------------->\u主__
__软件包----------------->无
多维数据集------->
广场------->
x------>5

我们感到困惑。square函数是否首先被推到堆栈上,并计算其返回值并传递给cube函数?另一种可能性是首先调用立方体函数,然后在解析参数的过程中,必须调用平方函数。你能告诉我们什么?这取决于编译器或语言吗?

当然,它可能取决于语言,但您的示例是Python

在Python中,函数参数总是在调用作为参数的函数之前进行求值。(请参阅。)由于
square(x)
作为
cube
的参数传递,因此首先调用
square
,然后将结果传递给
cube
。换句话说,表达式中的函数调用总是“由内而外”求值,最里面的函数调用首先求值。这就像数学表达式的求值顺序一样(最里面的括号在前)


参数在传递之前进行求值。也许可以这样写,使事情以另一种方式发生,但我不知道有哪种语言能做到这一点,因为它看起来非常不直观。

最里面的总是先求值,也就是说,它是最后一个放在堆栈上的

看看这个例子:

>>> def func():
        def func1():
            print (1)
        def func2(x):
            print (2)
        def func3(y):
            print (3)
        func3(func2(func1()))


>>> func()
1                         #func1() was called first
2                         #then func2()   
3                         #last is func3() 
使用
dis.dis()

dis.dis(func) 2 0加载常数1(<0xb76aa770处的代码对象func1,文件“pyshell”19,第2行>) 3生成函数0 6存储快速0(功能1) 4 9加载常数2(<0x8a10530处的代码对象func2,文件“pyshell”19,第4行>) 12生成函数0 15门店快速1(功能2) 6 18加载常量3(<0x8a102f0处的代码对象func3,文件“pyshell”19,第6行>) 21生成函数0 24商店快速2(功能3) 8 27加载快2(func3)#func3放置在堆栈上 30 LOAD_FAST 1(func2)#func2放置在堆栈上 33加载快0(func1)#最后是func1得到 #堆放 36调用函数0 39调用函数1 42调用函数1 45 POP_TOP#删除堆栈顶部项目。 46负载常数0(无) 49返回值
C的行为类似吗?根据文档,这看起来是正确的。我很快就会接受。是的,根据C99规范,“在准备调用函数时,对参数进行求值,并为每个参数分配相应参数的值。”Haskell就是一个不以这种方式工作的语言示例,我不知道dis。dis Dat太酷了!谢谢你,阿什维尼!
>>> def func():
        def func1():
            print (1)
        def func2(x):
            print (2)
        def func3(y):
            print (3)
        func3(func2(func1()))


>>> func()
1                         #func1() was called first
2                         #then func2()   
3                         #last is func3() 
>>> dis.dis(func)
  2           0 LOAD_CONST               1 (<code object func1 at 0xb76aa770, file "<pyshell#19>", line 2>)
              3 MAKE_FUNCTION            0
              6 STORE_FAST               0 (func1)

  4           9 LOAD_CONST               2 (<code object func2 at 0x8a10530, file "<pyshell#19>", line 4>)
             12 MAKE_FUNCTION            0
             15 STORE_FAST               1 (func2)

  6          18 LOAD_CONST               3 (<code object func3 at 0x8a102f0, file "<pyshell#19>", line 6>)
             21 MAKE_FUNCTION            0
             24 STORE_FAST               2 (func3)

  8          27 LOAD_FAST                2 (func3)      #func3 is placed on stack
             30 LOAD_FAST                1 (func2)      #func2 gets placed on the stack
             33 LOAD_FAST                0 (func1)      #finally it's func1 that gets
                                                        # placed on stack
             36 CALL_FUNCTION            0
             39 CALL_FUNCTION            1
             42 CALL_FUNCTION            1
             45 POP_TOP                          #Removes the top-of-stack item.
             46 LOAD_CONST               0 (None)
             49 RETURN_VALUE