什么是装饰器
目的:用于在源码中标记函数,以某种方式增强函数的行为。
特征:装饰器是可调用对象,其参数是一个函数(被装饰的函数),可能会处理这个函数,将其返回,或者将其替换成另一个可调用对象。
有两大特性
1,把被装饰的函数替换成其他函数
2,装饰器在加载模块时立即执行
缺点:
改变被装饰函数的name属性(解决这一点,可以使用functools.wraps 装饰器)
增加一个带参数的装饰器
什么是闭包
之前需要理解什么是局部变量、自由变量
局部变量:函数体内部定义的变量,只能内部使用,不能外部调用
自由变量:未在本地作用域绑定的变量
闭包是一种函数,会保留定义函数时存在的自由变量的绑定,这样调用函数时,虽然定义作用域不可用,但是仍能使用那些绑定。
函数返回,本地作用域也一去不复返。
特征:延伸了函数作用域,返回后依然保留了对自由变量的绑定
场景:avg(num) 会保留之前计算的数据
什么是nonlocal声明
为什么需要nonlocals声明:
当自由变量是不可变对象时,当尝试重新绑定时,例如 c += 1, 会隐士创建局部变量c, 这样c 就不是自由变量。
作用:
把变量标记成自由变量
标准库中的装饰器
# functools.lru_cache
#把耗时的函数结果保存,避免当传入相同参数时重复计算,LRU是一种算法,不用的缓存会被清除
@lru_cache
@clock
def fib():
pass
# functools.singledispatch
#替代if else 分发算法单分派函数