## 函数、作用域与抽象
#### 函数的定义
def name of function(list of formal parameters):
body of function
函数被调用时,会执行以下过程:
1. 构成实参的表达式被求值,函数的形参被绑定到求值结果。例如调用macVal(3+4,z)会在解释器求值这次调用时讲形参绑定到7,将形参y绑定到变量Z的值;
2. 执行点(要执行的下一条指令)从调用点转到函数体的第一条语句
3. 执行函数体中的代码,直至遇到return语句,这时,return后面的表达式的值就成为这次函数调用的值。或者没有语句可以继续执行,这时函数返回值为NOne;如果return后面没有表达式,这次调用的值也为NOne。
4. 这次函数调用的值就是返回值
5. 执行点移动到紧跟在这次函数调用后面的代码。
参数有一个特性,称为Lambda抽象。它允许程序员编写的代码所处理的不是具体对象,而是函数调用者选定用作实参的任何对象。
#### 关键字参数和默认值
位置参数:第一个形参帮到第一个实参,第二个形参绑到了第二个实参,以此类推。
关键字参数:形参根据名称绑定到实参。 关键字参数可以在实参列表中以任意顺序出现,但将关键字参数放在非关键字参数后面是不合法的。 关键字参数经常与默认参数值结合使用。
#### 作用域
1. 在最顶层,比如shell层,有一个符号表会跟踪记录这一层所有的名称定义和它们当前的绑定。
2. 调用函数时,会建立一个新的符号表(常称为栈帧)。这个表跟踪记录函数中所有的名称定义(包括形参)和它们当前的绑定。若果函数体内又调用了一个函数,就再建立一个栈帧。
3. 函数结束时,它的栈帧也随之消失。
注意:函数中使用局部变量,作用域的微妙之处毫无影响。
函数的规范定义了函数编写者与使用者之间的约定。我们将函数使用者称为客户。可以认为约定包括以下两个部分:
1. 假设:客户使用函数时必须满足的前提条件,通常是对实参的限制。它几乎总是限定每个参数可以接受的变量类型,偶尔对一个或多个参数的取值添加限制条件。
2. 保证:调用方法满足条件时,函数应当实现的功能。函数findRoot的文档字符串后两行描述了函数不想实现的结果保证。