来源:自学PHP网 时间:2020-09-27 14:58 作者:小飞侠 阅读:次
[导读] 通俗讲解python 装饰器...
今天带来通俗讲解python 装饰器教程详解
装饰器其实一直是我的一个"老大难"。这个知识点就放在那,但是拖延症。。。 其实在平常写写脚本的过程中,这个知识点你可能用到不多 但在面试的时候,这可是一个高频问题。 一、什么是装饰器 所谓的装饰器,其实就是通过装饰器函数,来修改原函数的一些功能,使得原函数不需要修改。 这一句话理解起来可能没那么轻松,那先来看一个"傻瓜"函数。 放心,绝对不是"Hello World"! def hello(): print("你好,装饰器") 肿么样,木骗你吧? 哈哈,这个函数不用运行相信大家都知道输出结果:"你好,装饰器"。 那如果我想让 那么,可以这样"增强"一下: def my_decorator(func): def wrapper(): print("这是装饰后具有的新输出") func() return wrapper def hello(): print("你好,装饰器") hello = my_decorator(hello) hello() 运行结果:
很显然,这个"增强"没啥作用,但是可以帮助理解装饰器。 当运行最后的
那上述代码里的 但是,python一直以"优雅"被人追捧,而上述的代码显然不够优雅。 二、优雅的装饰器 所以,想让上述装饰器变得优雅,可以这样写: def my_decorator(func): def wrapper(): print("这是装饰后具有的新输出") func() return wrapper @my_decorator def hello(): print("你好,装饰器") hello() 这里的 那如果还有其他函数也需要加上类似的装饰,直接在函数的上方加上 def my_decorator(func): def wrapper(): print("这是装饰后具有的新输出") func() return wrapper @my_decorator def hello(): print("你好,装饰器") @my_decorator def hello2(): print("你好,装饰器2") hello2() 输出:
三、带参数的装饰器 1. 单个参数 上面的只是一个非常简单的装饰器,但是实际场景中,很多函数都是要带有参数的,比如hello(people_name)。 其实也很简单,要什么我们就给什么呗,直接在对应装饰器的 def my_decorator(func): def wrapper(people_name): print("这是装饰后具有的新输出") func(people_name) return wrapper @my_decorator def hello(people_name): print("你好,{}".format(people_name)) hello("张三") 输出:
2. 多个参数 但是还没完,这样虽然简单,但是随之而来另一个问题:因为并不是所有函数参数都是一样的, @my_decorator def hello3(speaker, listener): print("{}对{}说你好!".format(speaker, listener)) 没关系,在python里, def my_decorator(func): def wrapper(*args, **kwargs): print("这是装饰后具有的新输出") func(*args, **kwargs) return wrapper @my_decorator def hello(people_name): print("你好,{}".format(people_name)) @my_decorator def hello3(speaker, listener): print("{}对{}说你好!".format(speaker, listener)) hello("老王") print("------------------------") hello3("张三", "李四") 同时运行下
3. 自定义参数 上面2种,装饰器都是接收外来的参数,其实装饰器还可以接收自己的参数。 def count(num): def my_decorator(func): def wrapper(*args, **kwargs): for i in range(num): print("这是装饰后具有的新输出") func(*args, **kwargs) return wrapper return my_decorator @count(3) def hello(people_name): print("你好,{}".format(people_name)) hello("老王") 注意,这里
4. 内置装饰器@functools.wrap 现在多做一步探索,我们来打印下下面例子中的hello()函数的元信息: def my_decorator(func): def wrapper(*args, **kwargs): print("这是装饰后具有的新输出") func(*args, **kwargs) return wrapper @my_decorator def hello(people_name): print("你好,{}".format(people_name)) print(hello.__name__) #看下hello函数的元信息 输出:
这说明了,它不再是以前的那个 如果我们需要用到元函数信息,那怎么保留它呢?这时候可以用内置装饰器 import functools def my_decorator(func): @functools.wraps(func) def wrapper(*args, **kwargs): print("这是装饰后具有的新输出") func(*args, **kwargs) return wrapper @my_decorator def hello(people_name): print("你好,{}".format(people_name)) print(hello.__name__) 运行下:
四、类装饰器 装饰器除了是函数之外,也可以是类。 但是类作为装饰器的话,需要依赖一个函数__call__(),当调用这个类的实例时,函数__call__()就 来改造下之前的例子,把函数装饰器改成类装饰器: class MyDecorator(): def __init__(self, func): self.func = func def __call__(self, *args, **kwargs): print("这是装饰后具有的新输出") return self.func(*args, **kwargs) # def my_decorator(func): # def wrapper(): # print("这是装饰后具有的新输出") # func() # return wrapper @MyDecorator def hello(): print("你好,装饰器") hello() 运行:
跟函数装饰器一样,实现一样的功能。 五、装饰器的嵌套 既然装饰器可以增强函数的功能,那如果有多个装饰器,我都想要怎么办? @decorator1 @decorator2 @decorator3 def hello(): ... 但是要注意这里的执行顺序,会从上到下去执行,可以来看下: def my_decorator(func): def wrapper(): print("这是装饰后具有的新输出") func() return wrapper def my_decorator2(func): def wrapper(): print("这是装饰后具有的新输出2") func() return wrapper def my_decorator3(func): def wrapper(): print("这是装饰后具有的新输出3") func() return wrapper @my_decorator @my_decorator2 @my_decorator3 def hello(): print("你好,装饰器") hello() 运行
好记性不如烂笔头,写一下理解一下会好很多。 以上就是通俗讲解python 装饰器的详细内容,更多关于python 装饰器的资料请关注自学php网其它相关文章! 以上就是关于通俗讲解python 装饰器全部内容,感谢大家支持自学php网。 |
自学PHP网专注网站建设学习,PHP程序学习,平面设计学习,以及操作系统学习
京ICP备14009008号-1@版权所有www.zixuephp.com
网站声明:本站所有视频,教程都由网友上传,站长收集和分享给大家学习使用,如由牵扯版权问题请联系站长邮箱904561283@qq.com