Python进阶(四):浅析装饰器(decorator)@
2017-10-17 21:00
323 查看
之前在看代码的时候看见有些代码会在函数前面用一个@+函数名修饰,开始有点困惑的。遂查找各种资料,才知道这是python的一种语法糖。虽然理解起来有点困难,可是理解过后就会佩服python的简洁性。
结果:
能够理解以上代码,其实就基本理解装饰器了
他主要就是将func2变成另一个函数而已。
执行结果:
我们先来看一下执行效果:
从结果可以看到,当我们在修饰时,就已经调用好了修饰函数func1修饰了,之后在调用的时候就不在调用修饰函数func1了。这里要注意的是,我们在定义修饰函数时必须在内部定一个新的函数insidefunc,然后在这个新的函数中进行操作后,最后返回这个insidefunc,也就是说func2已经变成了insidefunc了
还有一些其他装饰器的用法,比如在类里面装饰函数,或者用类来装饰就不一一展开了
主要应用于几个方面:参数检查、统计时间、缓存、注册回调函数、函数加日志 、线程异步等等
举个例子多线程异步:
详细用途可以看看官方文档:https://wiki.python.org/moin/PythonDecoratorLibrary
好了,今天就到这。谢谢浏览。
有问题探讨加QQ:1043601529。
装饰器@
一.介绍
函数就是我们的衣服,单个函数就比如一件短袖衬衫。编程就是不断的调用不同的函数,就比我们身上穿不同的衣服。当天气变凉的时候我们就必须加外套了,相同的我们需要对某个函数进行某种操作(并且并不想改变这个函数的内部结构)的时候,装饰器就派上了用场。比如我们想知道一个函数完整的执行时间,那么我们可以编写另一个函数B,然后将函数A传递进去,在B的内部计算函数A的执行时间。编写函数B的好处就是下次还要用到的使用就可以直接调用了。但是如果我们在写函数A的时候就想实现计算这个函数A的执行时间(就是每次调用的时候都会计算执行时间),那有什么办法呢?这是@装饰器就起作用了,而且可以很简洁的表示出来def B(): pass @B def A(): pass ''' 上面的代码相当于 A=B(A) '''
二.通过代码来理解
1.函数的调用
函数在python中是可以作为变量,或者说作为实参传入一个函数的:def func1(func): print("Start func1") func() print("End func1") def func2(): print("Start func2") print("End func2") func1(func2)
结果:
2.函数的嵌套
这一步,我们在升级一下。加一个函数的嵌套,说白了就是在一个函数中定义一个新的函数。def func1(func): print("This is func1") def insidefunc(): print("This is the inside function") func() print("Inside function end") print("func1 end\n") return insidefunc def func2(): print("This func2") print("func2 end\n") print("start:") print("func2 name:", func2.__name__, "\n") print("To decorate:") func2 = func1(func2) print("end:") print("func2 name", func2.__name__, "\n") func2()
能够理解以上代码,其实就基本理解装饰器了
他主要就是将func2变成另一个函数而已。
执行结果:
3.运用装饰器
好了我们开始运用装饰器吧def func1(func): print("This is func1") def insidefunc(): print("This is inside function") func() print("Inside function end") print("func1 end\n") return insidefunc @func1 def func2(): print("This is func2") print("func2 end") print("start:") print("func2 name:", func2.__name__) func2()
我们先来看一下执行效果:
从结果可以看到,当我们在修饰时,就已经调用好了修饰函数func1修饰了,之后在调用的时候就不在调用修饰函数func1了。这里要注意的是,我们在定义修饰函数时必须在内部定一个新的函数insidefunc,然后在这个新的函数中进行操作后,最后返回这个insidefunc,也就是说func2已经变成了insidefunc了
4.被修饰的函数传入参数
当然,我们的被修饰函数是可以传入函数的。只不过我们需要在修饰函数的内部函数insidefunc的()的参数与被修饰函数的参数数量一致就好。def func1(func): print("This is func1") def insidefunc(a, b): print("This inside function") a = func(a, b) print("Parameter from func:", a) print("Inside function end") print("func1 end\n") return insidefunc @func1 def func2(a, b): print("This is func2") print("func2 end") return a + b print("start") func2(4, 5)
5.修饰函数传入参数
我们的修饰函数也是可以传入参数的def func1(arg=True): if arg: def _func1(func): print("This in _func1") def insidefunc(a, b): print("This is in _func1.insidefunc") c = func(a, b) return c return insidefunc return _func1 else: def _wfunc1(func): print("This is _wfunc1") return func return _wfunc1 @func1(True) def func2(a, b): print("This func2") return a + b @func1(False) def func3(a, b): print("This is func3") return a * b print(func2(4, 5)) print("\n") print(func3(4, 5))
6.装饰器的连续套用
def func1(func): def _func1(a): print("This is _func1") a = func(a) return a * a return _func1 def func2(func): def _func2(a): print("This is _func2") a = func(a) return a * 3 return _func2 @func1 @func2 def func3(a): print("This is func3") return a print("Start:") print(func3(1)) print(func3(2))
还有一些其他装饰器的用法,比如在类里面装饰函数,或者用类来装饰就不一一展开了
三.装饰器的主要用途
说了这么多,大家可能对装饰器到底在实际开发中有什么应用还是很困惑的。其实在实际的开发中,装饰器还是很常见的,而且用处还很大。主要应用于几个方面:参数检查、统计时间、缓存、注册回调函数、函数加日志 、线程异步等等
举个例子多线程异步:
from threading import Thread from functools import wraps def async(func): @wraps(func) def async_func(*args, **kwargs): func_hl = Thread(target=func, args=args, kwargs=kwargs) func_hl.start() return func_hl return async_func if __name__ == '__main__': from time import sleep @async def print_somedata(): print('starting print_somedata') sleep(2) print('print_somedata: 2 sec passed') sleep(2) print('print_somedata: 2 sec passed') sleep(2) print('finished print_somedata') @async def _print_somedata(): print('starting _print_somedata') sleep(2) print('_print_somedata: 2 sec passed') sleep(2) print('_print_somedata: 2 sec passed') sleep(2) print('finished _print_somedata') def main(): print_somedata() print('back in main') _print_somedata() print('back in main') main()
详细用途可以看看官方文档:https://wiki.python.org/moin/PythonDecoratorLibrary
好了,今天就到这。谢谢浏览。
有问题探讨加QQ:1043601529。
相关文章推荐
- Python进阶之装饰器@decorator
- 对Python中装饰器(Decorator)的理解与进阶
- Python进阶(八)-编写带参数decorator
- Python进阶(六)-python编写无参数decorator
- python decorator 进阶
- Python进阶之“属性(property)”详解
- 机器学习算法与Python实践之(三)支持向量机(SVM)进阶
- 干货|python进阶系列(一)--装饰器
- Python进阶 函数式编程和面向对象编程等
- Python进阶
- 胶水语言Python技术百问_从新手到进阶
- python中的装饰器Decorator用法
- 跟我一起学python(六),面对对象--进阶篇
- python进阶学习笔记(三)
- Python学习笔记——decorator
- python深入学习--decorator强大的装饰器
- python进阶学习笔记(四)——python中访问限制、创建类属性、定义实例方法、定义类方法、类的继承
- 使用PyInstaller2将Python脚本转化为可执行文件(下-进阶使用)(转载自博客园balian)
- python进阶教程之文本文件的读取和写入
- ython进阶(二)——Python对象类型