一、闭包
1.1闭包的定义
在函数嵌套的前提下,内部函数使用了外部函数的变量,并且外部函数返回了内部函数,我们把这个使用外部函数变量的内部函数称为闭包。
1.2闭包的构成条件
(1)函数嵌套
简单的实例:
1 # 外部函数 2 def fun_out(a): 3 # 内部函数 4 def fun_inner(b): 5 result = a + b 6 print(result) 7 8 # 外部函数返回了内部函数,这里返回的内部函数就是闭包 9 return fun_inner 10 11 # 创建闭包实例 12 function = fun_out(1) 13 function(2)
》3
想要在内部函数中修改外部函数的变量或者是参数需要在内部函数中用nonlocal关键字声明外部函数的变量或者是参数。
1 #外部函数 2 def fun_out(): 3 num1 = 5 4 #内部函数 5 def fun_inner(num2) : 6 #使用nonlocal关键字声明外部函数的变量 7 nonlocal num1 8 num1=20 9 #内部函数使用了外部函数的参数num1 10 result=num1+num2 11 print("sum:"result) 12 return fun_inner
闭包可以保存外部函数内的变量,不会随着外部函数调用完而销毁。
注意点:
二、装饰器
2.1、装饰器的定义
装饰器就是给已经存在的函数添加额外功能的函数,它本质上就是一个闭包函数
2.2、装饰器的特点
2.3、实例代码
1 # 添加一个登录验证的功能 2 def check(fun): 3 def inner(): 4 print("请先登录....") 5 fun() 6 return inner 7 8 def comment(): 9 print("发表评论") 10 11 12 # 使用装饰器来装饰函数 13 comment = check(comment) 14 comment()
注意点:
2.4、装饰器的语法糖写法
Python给提供了一个装饰函数更加简单的写法,那就是语法糖,语法糖的书写格式是: @装饰器名字,通过语法糖的方式也可以完成对已有函数的装饰。
# 添加一个登录验证的功能 def check(fun): def inner(): print("请先登录....") fun() return inner # 使用语法糖来装饰函数 @check def comment(): print("发表评论") comment()
注意:
-
-
- @check 等价于 comment = check(comment)
- 装饰器的执行时间是加载模块时立即执行。
-
2.5、多个装饰器的使用
1 @test2 2 @test1 3 def index(): 4 return "BLUE" 5 6 #装饰过程index = test1(test2(index)) 7 #多个装饰器可以对函数进行多个功能的装饰,装饰顺序是由内到外的进行装饰
2.6、带有参数的装饰器
带有参数的装饰器就是使用装饰器装饰函数的时候可以传入指定参数,语法格式: @装饰器(参数,...)
1 # 添加输出日志的功能 2 def logging(flag): 3 4 def decorator(fn): 5 def inner(num1, num2): 6 if flag == "+": 7 print("--正在努力加法计算--") 8 elif flag == "-": 9 print("--正在努力减法计算--") 10 result = fn(num1, num2) 11 return result 12 return inner 13 14 # 返回装饰器 15 return decorator 16 17 18 # 使用装饰器装饰函数 19 @logging("+") 20 def add(a, b): 21 result = a + b 22 return result 23 24 25 @logging("-") 26 def sub(a, b): 27 result = a - b 28 return result 29 30 result = add(1, 2) 31 print(result) 32 33 result = sub(1, 2) 34 print(result)
注意:
类装饰器
装饰器还有一种特殊的用法就是类装饰器,就是通过定义一个类来装饰函数。
1 class Check(object): 2 def __init__(self, fn): 3 # 初始化操作在此完成 4 self.__fn = fn 5 6 # 实现__call__方法,表示对象是一个可调用对象,可以像调用函数一样进行调用。 7 def __call__(self, *args, **kwargs): 8 # 添加装饰功能 9 print("请先登陆...") 10 self.__fn() 11 12 13 @Check 14 def comment(): 15 print("发表评论") 16 17 18 comment()
- @Check 等价于 comment = Check(comment), 所以需要提供一个init方法,并多增加一个fn参数。
- 要想类的实例对象能够像函数一样调用,需要在类里面使用call方法,把类的实例变成可调用对象(callable),也就是说可以像调用函数一样进行调用。
- 在call方法里进行对fn函数的装饰,可以添加额外的功能。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。