闭包定义
在函数嵌套(函数里面再定义函数)的前提下,内部函数使用了外部函数的变量或参数,并且外部函数返回了内部函数。于是将这个使用外部函数变量或参数的内部函数称为闭包
- 可以保存外部函数内的变量
参数和变量
# coding=utf-8def func_out(): # 定义一个外部函数num1 = 10 # 外部函数变量def func_inner(num2): # 定义一个内部函数result = num1 + num2 # 内部函数使用外部函数的变量,可以将外部函数变量暂时保存print(result)return func_inner # 外部函数返回内部函数result = func_out() # 结果是内部函数 result = func_innerresult(1) # 函数调用,因为返回的是函数---------------------------------------------------------------------------------------------->>> 11
# coding=utf-8def conf_name(name):def inner(msg):print(name + ':' + msg) # 内部函数调用外部函数参数return innerkuma = conf_name('kuma')jerry = conf_name('jerry')kuma('小姐姐过来玩呀')jerry('滚犊子')-------------------------------------->>> kuma:小姐姐过来玩呀>>> jerry:滚犊子
修改外部变量
# coding=utf-8def func_out():num1 = 10def func_inner():nonlocal num1 # 闭包中使用关键字 nonlocal 声明全局变量num1 = 20result = num1 + 10print(result)return func_innerresult = func_out()result()---------------------------------->>> 30
装饰器
就是给已有函数增加额外功能的函数,本质就是一个闭包函数
def decorator(func): def inner(): func() # 内部函数使用外部有且仅有一个并且是函数类型的参数 print(‘恭喜您登录成功’) return inner
@decorator # 要写在已有函数前(后面不能写其他代码),相当于 comment = decorator(comment)
def comment(): print(‘请您输入密码’)
comment = decorator(comment) # 如果不写语法糖写法
comment()
请您输入密码 恭喜您登录成功 ```
被装饰函数有参数
# coding=utf-8def decorate(func):def inner(a, b):print('正在执行运算') # 对已有函数进行装饰func(a, b)return inner@decorate # 等价于 add_num = decorate(add_num)def add_num(num1, num2):result = num1 + num2print(result)add_num(1, 2)
内部函数的类型和被装饰的函数的类型是保持一致的
被装饰函数有返回值
# coding=utf-8def decorate(func):def inner(a, b):print('正在执行运算')num = func(a, b)return num # 内部函数的类型和被装饰的函数的类型是保持一致的,即被装饰函数有返回值内部函数也要有return inner@decoratedef add_num(num1, num2):result = num1 + num2return resultresult = add_num(1, 2)print(result)
被装饰函数有缺省参数
# coding=utf-8def decorate(func):def inner(*args, **kwargs):print('正在执行运算')num = func(*args, **kwargs)return numreturn inner@decoratedef add_num(*args, **kwargs):result = 0for i in args:result += ifor i in kwargs.values():result += ireturn resultresult = add_num(1, 2, age=20)print(result)
多装饰器
# coding-utf-8def make_p(func):def inner():result = '<p>' + func() + '</p>'return resultreturn innerdef make_div(func):def inner():result = '<div>' + func() + '</div>'return resultreturn inner@make_div@make_pdef content():return 'happy kuma'result = content()print(result)
由内到外的装饰过程,即 make_div(make_p(content))
装饰器带有参数
# coding=utf-8def return_decorate(flag):def decorate(func):def inner(a, b):if flag == "+":print('正在执行加法运算')else:print('正在执行减法运算')func(a, b)return innerreturn decorate@return_decorate("+")def add_num(a, b):result = a + bprint(result)add_num(1, 2)@return_decorate("-")def add_num(a, b):result = a - bprint(result)add_num(1, 2)
区别
闭包一定是装饰器,但装饰器不一定是闭包的原因:如果外部函数的参数有且只有一个。并且是函数类型在内部函数使用,那么这个闭包函数就是装饰器。
