变量作用域、参数传递、参数类型、lambda表达式与匿名函数、eval()函数、递归函数
一、变量的作用域
变量起作用的范围称为变量的作用域,不同作用域内同名变量之间互不影响。分为:全局变量和局部变量。
全局变量:
- 在函数和类定义之外申明的变量。作用域为定义的模块,从定义位置开始直到模块结束。
- 全局变量降低了函数的通用性和可读性。应尽量避免全局变量的使用。
- 全局变量一般作常量使用。
- 函数内要改变全局变量的值,使用global申明一下
局部变量:
- 在函数体中(包含形式参数)申明的变量。
- 局部变量引用比全局变量快,优先考虑使用。
- 如果如果局部变量和全局变量同名,则在函数内隐藏全局变量,只使用局部变量。
二、参数的传递
函数的参数传递本质上就是:从实参到形参的赋值操作。Python中“一切皆对象”,所有的复制操作都是“引用的赋值”。所以python中参数的传递都是“引用传递”,不是“值传递”。具体分为两类:
- 对“可变对象”进行“写操作”,直接作用于原对象本身。
- 对“不可变对象”进行“写操作”,会产生一个新的“对象空间”,并用新的值填充这块空间(起到其他语言的“值传递”效果,但不是“值传递”)
可变对象有:字典、列表、集合、自定义的对象等;
不可变的对象有:数字、元组、字符串、function等。
浅拷贝与深拷贝
浅拷贝:不拷贝子对象的内容,只拷贝子对象的引用。
深拷贝:会连子对象的内存也全部拷贝一份,对子对象的修改不会影响源对象。
三、参数的类型
- 位置参数:
函数调用时,实参默认按位置顺序传递,需要个数和形参匹配。按位置传递的参数,称为:“位置参数”。 - 默认值参数:
可以把某些参数设置默认值,这些参数在传递时就是可选的。称为:“默认值参数”。默认值参数放到普通位置参数后面。 - 命名参数:
可以按照形参的名称传递参数,称为“命名参数”,也称为“关键字参数”。 - 可变参数:
可变参数指的是“可变数量的参数”。分两种情况:
1.*param(一个星号),将多个参数收集到一个“元组”对象中。
2.**param(两个星号),将多个参数收集到一个“字典”对象中。 - 强制命名参数:
在带星号的“可变参数”后面增加新的参数,必须在调用的时候“强制命名参数”。
四、lambda表达式和匿名参数
lambda表达式可以用来申明匿名参数。lambda函数是一种简单的、在同一行中定义函数的方法。lambda函数实际生成了一个函数对象。
lambda表达式只允许包含一个表达式,不能包含复杂语句,该表达式的计算结果就是函数的返回值。
lambda表达式的基本语法:
lambda arg1,arg2,arg3,… : <表达式>
arg1,arg2,arg3为函数的参数。 <表达式>相当于函数体。运算结果是:表达式的运算结果。
五、eval()函数
功能:将字符串str当成有效的表达式来求值并返回计算结果。
语法:eval(source[,globals[,locals]]) -> value
参数:
source:一个python表达式或函数compile()返回的代码对象
globals: 可选。必须是dictionary
locals: 可选。任意映射对象
六、递归函数
递归函数指的是:自己调用自己的函数,在函数体内部直接或间接的自己调用自己。递归类似于数学学习中的“数学归纳法”。每个递归函数必须包含两个部分:
- 终止条件:表示递归什么时候结束。一般用于返回值,不再调用自己。
- 递归步骤:把n步的值和n-1步相关联。