什么是装饰器

目的:用于在源码中标记函数,以某种方式增强函数的行为。

特征:装饰器是可调用对象,其参数是一个函数(被装饰的函数),可能会处理这个函数,将其返回,或者将其替换成另一个可调用对象。

有两大特性

  1. 1,把被装饰的函数替换成其他函数
  2. 2,装饰器在加载模块时立即执行

缺点:

  1. 改变被装饰函数的name属性(解决这一点,可以使用functools.wraps 装饰器)

增加一个带参数的装饰器

什么是闭包

之前需要理解什么是局部变量、自由变量

  1. 局部变量:函数体内部定义的变量,只能内部使用,不能外部调用
  2. 自由变量:未在本地作用域绑定的变量

闭包是一种函数,会保留定义函数时存在的自由变量的绑定,这样调用函数时,虽然定义作用域不可用,但是仍能使用那些绑定。

函数返回,本地作用域也一去不复返。

特征:延伸了函数作用域,返回后依然保留了对自由变量的绑定

场景:avg(num) 会保留之前计算的数据

什么是nonlocal声明

为什么需要nonlocals声明:

  1. 当自由变量是不可变对象时,当尝试重新绑定时,例如 c += 1, 会隐士创建局部变量c, 这样c 就不是自由变量。

作用:

  1. 把变量标记成自由变量

标准库中的装饰器

  1. # functools.lru_cache
  2. #把耗时的函数结果保存,避免当传入相同参数时重复计算,LRU是一种算法,不用的缓存会被清除
  3. @lru_cache
  4. @clock
  5. def fib():
  6. pass
  7. # functools.singledispatch
  8. #替代if else 分发算法单分派函数

应用