1. 函数的定义和调用
def 函数名([参数列表]):
'''文档字符串'''
函数体/若干语句
- 要点
- 使用def定义函数;
- 参数列表
- 圆括号内是形参列表,用逗号隔开;
- 形参不需要声明类型,也不需要指定函数返回值类型;
- 无参数时,圆括号必须保留;
- 实参、形参列表需要一一对应;
- return返回值
- 如果函数体中包含return语句,则结束函数执行并返回值;
- 如果函数体中不包含return语句,则返回None;
- 多个返回值,可以使用列表、元组、字典、集合将多个值存起来
- 调用前必须先定义;
- 内置函数对象自动创建;
- 标准库 or 第三方库需使用 import 导入;
2. 变量的作用域
2.1 全局变量
- 在函数和类定义之外声明的变量;
- 全局变量降低了函数的通用性和可读性,应尽量避免使用;
- 全局变量一般做常量使用;
- 函数内要改变全局变量的值,需使用global声明一下。
2.2 局部变量
- 在函数体中(含形式参数)声明的变量;
- 局部变量的引用快,优先考虑使用;
- 如果局部变量和全局变量名称相同,则只使用同名的局部变量。
3. 参数的传递
python中参数的传递都是“引用传递”;
3.1 传递可变对象的引用
- 可变对象:字典、列表、集合、自定义对象;
- 直接作用于原对象本身;
- 实际上传递的还是对象的引用,在函数体中不创建新的对象的拷贝,而是可以直接修改所传递的对象;
3.2 传递不可变对象的引用
- 不可变对象:数字、字符串、元组、function等;
- 会产生新的“对象空间”,并用新的值填充这块空间;
- 实际传递的还是对象的引用,在“赋值操作”时,由于不可变对象无法修改,系统会创建一个新对象;
4. 浅拷贝 & 深拷贝
- 浅拷贝:不拷贝子对象的内容,只是拷贝子对象的引用;
import copy
def testCopy():
a = [10, 20,[5, 6]]
b = copy.copy.(a)
print('a:', a)
print('b:', b)
b.append(30)
b[2].append(7)
print("浅拷贝后--------")
print('a:', a)
print('b:', b)
- 深拷贝:会连子对象的内存也全部拷贝一份,对子对象的修改不会影响原对象。
import copy
def testDeepCopy():
a = [10, 20,[5, 6]]
b = copy.copy.(a)
print('a:', a)
print('b:', b)
b.append(30)
b[2].append(7)
print("深拷贝后--------")
print('a:', a)
print('b:', b)
5. 参数的几种类型
- 位置参数:函数调用时,实参默认按位置顺序传递;
- 默认值参数:可以为某些参数数默认值,默认值参数在位置参数后;
- 命名参数:使用形参的名称传递参数,也称为“关键字参数”;
- 可变参数:可变数量的参数;
- ‘* param’,将多个参数收集到一个“元组”对象中;
- ‘** param’,将多个参数收集到一个“字典”对象中;
- 强制命名参数:带星号的可变参数后新增加的参数,必须是“强制命名参数”;
6. lambda 表达式和匿名函数
- lambda表达式可以用来声明匿名函数;
- lambda函数是一种简单的、在同一行中定义函数的方法,实际上生成了一个函数对象;
- 只允许包含一个表达式,不能包含复杂语句,该表达式的计算结果就是函数的返回值;
lambda arg1, arg2, arg3... : <表达式>
f = lambda a, b, c : a + b + c
print(f(2, 3, 4))
g = [lambda a : a*2, lambda b : b*3, lambda c : c*4]
print(g[0](6), g[1](7), g[2](8))
7. eval()
- 将字符串str当成有效的表达式来求值并返回计算结果;
eval(source[,globals[,locals]])->value
- source:一个python表达式或者函数compile()返回的代码对象;
- globals:可选,必须是dictionary;
- locals:可选,任意映射对象;
8. 递归函数
- 终止条件:确定递归何时结束,一般用于返回值;
- 递归步骤:把第n步的值和第n-1步相关联;
- 递归函数会创建大量的函数对象,耗内存和运算能力,大量数据时不推荐使用;
|