cs61a-How to draw an Environment Diagram(1.6)
How to draw an Environment Diagram
概念
这里解释下打星号的2:
Copy the parent of the function to the local frame: [parent=<label>]
:意思是将定义原函数的frame
名称作为<label>
,放在这个local frame: [parent=<label>]
中。
举例
下面举个例子(代码来自1.6 Higher-Order Functions的1.6.3 Defining Functions III: Nested Definitions
):
def average(x, y):
return (x + y)/2
def improve(update, close, guess=1):
while not close(guess):
guess = update(guess)
return guess
def approx_eq(x, y, tolerance=1e-3):
return abs(x - y) < tolerance
def sqrt(a):
def sqrt_update(x):
return average(x, a/x)
def sqrt_close(x):
return approx_eq(x * x, a)
return improve(sqrt_update, sqrt_close)
result = sqrt(256)
让我们看下当程序执行到sqrt(256)
但是还未执行到return improve(sqrt_update, sqrt_close)
时候的环境:
分析
可以得知当调用存在于[parent= Globa]
函数sqrt()
的时候:
- 新增本地栈:新增一个名为
sqrt
的本地栈,代号为f1
。(todo:f1
应该是代号或者标签,类似指针的作用,下面统一用“标签”)。 - 注明上级栈:
The parent of a function is the frame in which it was defined
。将原型函数sqrt()
的栈Global
作为这个本地栈sqrt
的上级栈。 - 参数传递:将传入的实参
256
赋值给形参a
,现在a = 256
。 - 嵌套函数定义:
sqrt_update(x)
和sqrt_close(x)
定义在此本地栈中,且两个函数的上级栈均为当前sqrt
的本地栈,即f1
。
从这个计算sqrt(256)
的部分,就可以将上面如何画好“调用函数和定义函数时候的环境图表”
的概念理解清晰了。
例子2:
>>> def cake():
... print('beets')
... def pie():
... print('sweets')
... return 'cake'
... return pie
>>> chocolate = cake()
分别写一下给chocolate
赋值时界面输出的文字和调用chocolate
的时候,输出的文字,并分析为什么。
这里就不文字描述了,提供一个Python图形化代码执行过程的网站,输入代码执行,多尝试一下~😉