python高级编程(四)--闭包、装饰器
来源:互联网 发布:初三物理视频教程软件 编辑:程序博客网 时间:2024/06/13 01:50
1. 闭包
- 说明:在一个函数中又定义了一个函数,并且内部函数可以引用外部函数的参数和局部变量,当外部函数返回内部函数时,相关参数和变量都保存在返回的函数中,这种称为闭包。
一个闭包的实际例子:
"""闭包的例子"""def line_conf(a,b): def line(x): return a*x + b return lineline1 = line_conf(1,1)line2 = line_conf(4,5)print(line1(5))print(line2(5))
结果:
6
25
- 闭包的优缺点:
优点:(1)闭包具有提高代码可复用性的作用(2)减少了代码的可移植性。
缺点:由于闭包引用了外部函数的局部变量,则外部函数的局部变量没有及时释放,消耗内存。
2. 装饰器
假设我们需要增强一个函数的功能,但又不希望修改函数的定义,在代码运行期间动态增加的方式,称为装饰器(Decorator)
- 装饰器的作用:
- 引入日志
- 函数执行时间统计
- 执行函数前预备处理
- 执行函数后清理功能
- 权限校验等场景
- 缓存
一个装饰器的例子:
def w1(func): def inner(): print("----权限验证----") func() return inner@w1def f1(): print("----f1----")
运行结果:
—-权限验证—-
—-f1—-
整个运行过程如下:
(1). def w1(func):—–> 将w1函数加载到内存
(2). @w1
: —-> 执行w1函数,并将@W1
下面的函数作为w1函数的参数,即@w1
等价于w1(f1)inner()函数,将执行完的W1函数返回值赋值给@w1
下面的函数的函数名f1即将w1的返回值再重新赋值给f1.
- 一个装饰器或多个装饰器使用:
# 定义函数:完成包裹数据def makeBold(func): def wrapped(): return "<b>" + func() + "</b>" return wrapped# 定义函数:完成包裹数据def makeItalic(func): def wrapped(): return "<i>" +func() + "</i>"@makeBolddef test1(): return "hello world-1"@makeItalicdef test2(): return "hello world-2"@makeBold@makeItalicdef test3(): return "hello world-3"print(test1())print(test2())print(test3())
- 装饰器–无参数的函数:
"""无参数的函数"""from time import ctime,sleepdef timefun(func): def wrapped_func(): print("---%s called at %s" %(func.__name__,ctime())) func() return wrapped_func# foo = timefun(foo) # foo 先作为参数赋值给func后,foo接收指向timefun返回的wrapped_func@timefundef foo(): print("我是无参数函数")foo()sleep(2)foo()# 调用foo(),即等价调用wrapped_func()# 内部函数wrapped_func被引用,所以外部函数的func变量(自由变量)并没有释放# func里保存的是原foo函数对象
运行结果:
— foo called at Sun Aug 13 17:12:21 2017
我是无参函数
— foo called at Sun Aug 13 17:12:21 2017
我是无参函数
- 装饰器–有参数函数
import timedef f(func): def wrapped_func(a,b) print(a,b) func(a,b) return wrapped_func@fdef test(a,b): print(a+b)test(3,5)time.sleep(2)test(2,4)
运行结果:
3,5
8
2,4
6
- 装饰器函数-不定长参数
import timedef f(func): def wrapped_func(*args, **kwargs): fun(*args,**kwargs) return wrappend_func@fdef test1(a,b,c): print(a+b+c)test(3,5,7)time.sleep(2)test(2,4,9)
- 装饰器–有return
import time def f(func): def wrapped_f(): print("====%s called ====="%func.__name__) f() return wrapped_f@fdef test(): print("I am test")@fdef getInfo(): return "---hello---"test()time.sleep(2)test()print(getInfo())
执行结果:
====test called =====
I am test
====test called =====
I am test
====getInfo called =====
None
如果装饰器为 return func() 运行结果:
====test called =====
I am test
====test called =====
I am test
====getInfo called =====
—hello—
- 装饰器–带参数,在原有装饰器的基础上,设置外部变量
import timedef f_arg(pre="hello"): def f(func): def wrapped_f(): print("===%s call ==="%func.__name__) return func return wrapped_func return f@f_arg("java")def test1(): print("I am test1")@f-arg("python")def test2(): print("I am test2")test1()time.sleep(2)test1()test2()time.sleep(2)test2()
运行结果:
====test1 called ===
====test1 called ===
====test2 called ===
====test2 called ===
====>>>>>>> 可以理解为 test() = f_arg(“java”)(test)()
装饰过程:
(1).调用f_arg(“hello”)
(2).将步骤1得到的返回值,即f返回,然后f()
(3).将f(test1)的结果返回,即wrapped_f
(4).让test1 = wrapped_f , 即test1现在指向wrapped_f
- 装饰器–类装饰器
"""类装饰器"""class Test(object): def __init__(self,func): print("==>>>初始化") print("==>>>func name is %s"%func.__name__) self.__func = func def __call__(self): print("====装饰器中的功能====") self.__func()@Testdef test(): print("====test====")test()
运行结果:
==>>>初始化
==>>>func name is test
====装饰器的功能====
====test====
说明:
(1). 当用Test来装作装饰器对test函数进行装饰的时候,首先会创建Test的实例对象。并且会把test这个函数名当做参数传递到__init__
方法中。即在__init__
方法中的属性self.__func
指向了test指向的函数。
(2). test指向了用Test创建出来的实例对象
(3). 当在使用test()进行调用时,就相当于让这个对象(),因此会调用这个对象的__call__
方法
(4). 为了能够在__call__
方法中调用原来test指向的函数体,所以在__init__
方法中就需要一个实例属性来保存这个函数体的引用
所以才有了self.__func
= func这句代码,从而在调用__call__
方法中能够调用到test之前的函数体。
- python高级编程(四)--闭包、装饰器
- Python高级编程--闭包与装饰器
- Python高级编程1-闭包,迭代器,装饰器,生成器
- Python高级编程之装饰器
- python高级编程-装饰器学习笔记
- Python闭包、函数式编程、装饰器深入理解
- python闭包,装饰器
- python 闭包&装饰器
- python--闭包,装饰器
- 【Python笔记】Python的几个高级语法概念浅析:lambda表达式 && 闭包 && 装饰器
- Python进阶笔记(2)_ 函数式编程 之 闭包和装饰器decorator
- python 高级编程 四
- Python高级编程——7.装饰器
- Python高级编程(四)多线程
- Python编程(四):两个实用的Python的装饰器
- python 嵌套函数、闭包装饰器、装饰器例子
- python的闭包和装饰器
- python装饰器和闭包
- 关联容器(set & multiset & Map& multimap)
- unity导入/播放视频问题
- 十四讲重新过一遍,今天进度到了第七讲,139页ORB特征点提取程序的部分参数解释如下
- 轮播图
- Balabolka(语音阅读器)官方中文版V2.11.0.638下载 | 含balabolka语音库下载 | 文本转语音软件
- python高级编程(四)--闭包、装饰器
- python对初一英语语法选择题转换
- Socket 网络编程
- 【前端前沿看点】深度本质分析对比weex和react native
- 第四篇 EditText与ScrollView滑动冲突
- HDU 6145 Arithmetic of Bomb II(数学+矩阵快速幂)
- 炉石辛达苟斯贫民打法
- 24. Swap Nodes in Pairs
- Java数据结构详解(十一)-Map接口