函数
概念
- python函数
- 由若干语句组成的语句块、函数名称、参数列表构成,是组织代码的最小单元
- 完成一定的功能
- 作用
- 按照功能组织封装一段代码
- 封装为了复用,减少冗余
- 代码简洁易读
- 分类
- 内建函数,如max(),reversed()…
- 库函数,如math.ceil()…
函数定义、调用
语法
def函数名(参数列表)
函数体(代码块)
[return 返回值]
- 定义
- 函数名就是标识符,保持缩进(4空格)
- python函数无return语句,
隐式返回None
- 定义中的参数列表为形式参数(形参)定义只是声明,不会执行
- 调用
fuction(argument)
- 调用的参数是实际参数(实参)
- 调用前必须定义,否则NameError异常
- 函数是可调用对象:callable()
- 定义
函数参数
- 参数调用时传入的参数要与定义的个数匹配(可变参数除外)
- 传参
- 位置参数必须在关键字参数之前传入
- 位置参数
- 按照参数定义的顺序传入实参
- 关键字参数
- 使用形参的名字传入实参,定义顺序与传参顺序可不同
函数参数缺省值
- 缺省值(默认值)
- 定义时,为形参赋值
- 作用
- 缺省值可在传入实参不足时,对未给定实参的形参赋缺省值
可变参数
- 可变位置参数
- 在形参前加注
*
(*args) - 可接收多个实参组成一个元组
- 在形参前加注
- 可变关键字参数
- 在形参前加注
**
(**kwargs) - 可接收多个关键字参数,收集实参名称和值组成一个字典
- 在形参前加注
keyword-only参数
def function(*,x,y):
- 在一个星号参数或可变位置参数之后出现的普通形参
- 只能关键字传参
- 可带缺省值
参数规则顺序
普通参数、缺省参数、可变位置参数(*args)、keyword-only参数(可带缺省值)、可变关键字参数(**kwargs)
参数解构
- 提供实参时,可在集合前使用
*
或**
,将集合结构解开,提取所有元素作为实参 非字典使用 *
解构成位置参数字典使用 **
解构成关键字参数- 取出的元素数目、类型必须与参数匹配
直接插入排序
- 在未排序的序列中,构建一个子排序序列,直至数据全部完成排序
- 将待排序的数,插入到已排序的序列中合适的位
- 增加一个哨兵,放入待比较值,使其与后面已排序的序列比较,找到合适的插入点
- 当序列为升序排列时比较迭代次数为n-1
- 当序列为降序排列时比较迭代次数为n(n-1)/2
时间复杂度为O(n²)
- 稳定排序方法
例题
返回值、作用域
返回值
- 作用:结束函数调用,返回“值”
- return语句返回“返回值”,若无return语句,则
隐式调用return None
- return语句不一定是函数语句块的最后一条语句
- 多个
return语句只执行一条
- 执行了
return则函数就会返回
,之后的其他语句都跳过 - 函数不能同时返回多个值
- return返回的是
一个
对象(列表/元组/字典…),多个值皆被隐式的封装成了一个元组 - 函数可以嵌套
作用域
- 一个标识符的可见范围即为标识符的作用域,多指变量的作用域
- 全局作用域
- 在整个程序运行环境中皆可见
- 局部作用域
- 在函数、类…内部可见
- 局部变量使用范围不能超过其所在的局部作用域
- 嵌套结构
- 外层变量作用域在内层作用域可见
- 内层作用域中对一个变量
重新定义
不会影响外层作用域
- global全局作用域
- 使变量由
局部作用域扩展至全局作用域
- 作用范围过大,与函数封装隔离用途不符,少用。函数使用外部变量通过形参传参解决
- 使变量由
闭包
- 自由变量:未在本地作用域中定义的变量。例如定义在内存函数外的外层函数的作用域中的变量
闭包:在嵌套函数中,内层函数引用到了外层函数的自由变量
nonlocal关键字
- 将变量标记为不在本地作用域定义,在
上级的某一级局部作用域
中定义,但不能是全局作用域
- 形成闭包运行
递归函数
概念
- 函数直接或间接调用自身
- 递归需要有
边界条件
、递归前进段、递归返回段 - 不满足边界条件时,递归前进
- 满足边界条件时,递归返回
间接递归
- 通过其它函数调用函数自身
- 易构成循环递归调用形成死循环。
避免这种递归调用
递归总结
- 递归是一种自然表达,符合逻辑思维,代码简洁
- 运行效率低,每次调用函数都要开辟栈帧,反复压栈。栈与线程相关,线程互不干扰
- Python对递归的调用深度做了限制以保护解释器
- sys.getrecursionlimit()
- 超过深度限制返回RecursionError异常
大多数递归皆可用循环实现,少用递归
例题
匿名函数
- 无名字的函数
- 高阶函数传参时使用,以简化代码
- 借助lambda表达式构建匿名函数
lambda 参数列表 :表达式
- 参数列表不需要小括号()
- 冒号:分割参数列表和表达式
- 不使用return,返回值即表达式的值
只能写在一行上,称为单行函数
- 语法:
lambda x : x ** 2 # 定义
(lambda x : x ** 2)(4) # 调用
生成器、yield
生成器
- 生成器generator
- 生成器对象,由生成器表达式得到;也可以使用yield关键字得到一个生成器函数,调用后即可得到一个生成器对象
- 生成器函数
函数体中包含yield语句的函数,返回生成器对象
生成器对象是一个可迭代对象、迭代器
生成器对象是惰性求值
生成器应用
- 无限循环
- 计数器
- 处理递归
- 协程coroutine
- 生成器的高级用法
- 比进程、线程轻量级
- 在用户空间调度函数的一种实现
- 非抢占式调度
- 协程调度器
- 两个生成器A,B
- 执行next(A)到yield暂停→执行next(B)到yield暂停→调用next(A)→调用next(B)…周而复始,实现调度的效果
- 可以引用调度的策略实现切换的方式
yield
- 多个yield语句,next(generator)执行后到第一个yield即暂停,并返回yield表达式的值
- 再次执行next会到下一个yield语句。没有多余的yield语句,再次调用next会返回StopIteration异常
- return可以终止函数,但无法获取return的返回值
- return导致无法获取下一个值,返回StopIteration异常
- 若函数无显式的return语句,当生成器函数执行完,也会返回StopIteration异常
yield from
- yield from iterable 是 for item in iterable : yield item 形式的语法糖
- 例:
for x in range(10):
⇔ yield from range(10)
yield x