本质: 语法糖( 实现闭包的一种语法糖 )
作用: 在不修改原函数的情况下, 对函数的功能进行添加; 提高代码可复用性的作用
何时运行: 只要遇到这句话就解析, 直接装饰( 在函数调用之前就已经装饰 )
应用
多层装饰: 像快递包裹: 包裹从内往外, 拆包从外往内
装饰顺序: 先判断下面是否为函数, 如果是函数才装饰;
调用顺序: 从上往下拆 (与装饰相反)
(被装饰的函数) 参数问题:
无参数 : def inner():
有参数: def inner( *args, **kwagrs ):
def set_func(func):
def call_func(*args, **kwargs):
# func(args, kwargs) # 不行, 相当于传递了2个参数: 1个字典,1个元组
func(*args, **kwargs) # 拆包
return call_func
(被装饰的函数) return问题:
def inner():
装饰器带有参数:
def set_level(level_num):
def set_func(func):
def call_func(*args, **kwargs):
if level_num == 1:
print("----authority level 1----")
else: level_num == 2:
print("----authority level 2----")
return func()
return call_func
return set_func
@set_level(1) # 调用set_level,并且将1当做实参传递;用它的返回值当做装饰器
def test1():
print("----test1----")
return "ok"
@set_level(2)
def test2():
print("----test2----")
return "ok"
test1()
test2()
类装饰器
class Test(object):
def __init__(self, func):
self.func = func
def __call__(self, *args, **kwargs):
return self.func(*args, **kwargs)
@Test # get_str = Test(get_str)
def get_str():
return "hah"
print(get_str())
三要素:
对比:
匿名函数: 能够完成 简单的功能, 只有功能
普通函数: 能够完成 较为复杂的功能, 只有功能
闭包: 能够完成 较为复杂的功能, 有功能 + 数据(函数仅仅有功能,闭包还有需要的数据)
闭包与函数的区别:
函数: 仅仅具有功能
闭包: 不仅仅具有功能, 还有需要的数据
闭包中修改变量:
全局变量: global
内部函数修改外部函数局部变量: nonlocal
闭包: 比函数多一些 特殊的数据(外部的全局变量), 比对象更小, 只有小部分数据 和 一段代码; 可以理解为轻量级的面向对象
进阶:
闭包 与 普通函数加上一个全局变量 的区别
闭包: 每一个闭包拥有自身独立的变量(轻度封装), 个人是个人,互不影响
全局+函数: 当在定义一个函数时,共享全局变量, 一方改变, 另一方立马就废了