装饰器

什么是装饰器

装饰器顾名思义就是一个有装饰功能的工具,那么装饰器又是用来装饰什么的?为什么要装饰这个东西?装饰的目的是什么呢?本文会一一作答让小弟一个一个说

开放封闭原则

谈及装饰器就要引申一个概念,那就是开放封闭原则,那么问题又来了 什么是开放封闭……好好好,直接说这个,开放封闭本来是两个对立的概念,也就是说是一对反义词,那么为什么要提出开放封闭原则呢?原因是在日常的开发工作中,一般最初上线的产品的功能是不尽完善的,就是说不够完美但已经能够支撑日常使用,其余的功能可以日后扩展,举例:N年前的QQ和现在的QQ(PS:虽然现在本人不怎么用了)。在后期扩展功能时,因为函数已经是写好的,而且存在大量调用,所以要直接去给函数增添新的功能显然不现实,所以我们只能新建函数去给原来的函数扩展功能(其实这就是一个装饰器啦)

那么开放封闭原则到底是什么? 答案是对源码封闭,对新功能开放

  • 封闭原则:不要改变源代码

  • 开放原则:能增加一些额外的功能

    如果还有客观对开放封闭原则似知似解的话,没关系接着往下看,不影响您食用本文,因为Python装饰器本身就是对开放封闭原则完美的诠释

装饰器初识

不低调的说,装饰器就是一个函数,名字本来很高大上,但本质就是一个函数,装饰器函数的功能就是要装饰一个函数,在不改变被装饰函数的源代码及调用方式的前提下,为其增加额外的功能。是不是有点门道了,是不是觉得这玩意也没啥啦,真是优秀的同学。

代码show(技术博客不写代码干白话说出去丢人)

def warpper(f):     #定义一个函数(装饰器),传入的参数是被修饰的函数的函数名

def inner(*args,**kwargs): #嵌套一个内存函数,这个函数主题才是执行被装饰函数源码的关键

    '''这块可以加要在被装饰函数执行之前的操作哈'''

    ret = f(*args,**kwargs) #这里的形参我会在下面说明

    '''这里可以写被装饰函数之后的,兄嘚,别客气,想加啥方法加什么'''

    return ret #这里的返回值如果我一会儿不忘的话也会在下面说明

return inner

@warpper #这个叫语法糖,嗯……可以吃(可能老外命名的时候就是这么想的),结构是@加函数名,作用下面会说明
def func():
  print('我就是那个被装饰的函数')
简单说明

因为本人比较懒,所以原谅我直接把代码甩上去了,后面有注释,看懂了的大佬可以say goodbye啦,想打我的接着听我白话,那我就把备注再重复一遍,哈哈,你也看到了,装饰器用到了函数的嵌套(再具体点就是闭包,要问什么是闭包,百度吧,哈哈),首先外层函数接收到一个函数名,然后返回值是内层函数的函数名;再来内层函数可以接收参数,其中ret = f(*args,**kwargs)有两个作用,一是执行了传入的函数,也就是执行了被修饰的函数,二是将返回值赋给了一个变量,此处要说明一下,对被修饰的函数功能的扩展要写在这里哦,最后 ret作为内层函数的返回值返回给函数执行者。

语法糖

@warpper这东西和 func = wrapper(func)是一样的,也就是说最后三行代码可以这样写

#@warpper   
def func():
  print('我就是那个被装饰的函数')
func = wrapper(func)   #注意奥,这玩意要写在被装饰函数的下边,语法糖才写上边

至于为什么要写着东西,或者为什么要用语法糖?请听下回分解~~~,收起你滴拳头,是这样,我刚开始的时候谈到了,装饰器是要在不改变源码和其调用方式的前提下给其增加新的功能,注意到了么 调用方式 嗯……没错就是调用方式,如果我不这样写那我是不是要wrapper(func)()这样去调用啊,是不是有点绕了,但是我把wrapper(func)赋值给了一个和被装饰函数同名的变量,那我此时要怎么调用,是不是就是func(),这样就满足了开放封闭原则,完美!其实本质就是要把装饰器“伪装”成原函数,包括调用方式、参数、返回值,装就要装的像一点,对吧。

装饰带参数的装饰器
def wrapper(f):
def inner(*args,**kwargs):
f(*args,**kwargs)
return inner
@wrapper
def func(a,b):
print(a,b)

函数func中有两个形参a和b,说一下这两个参数在装饰器中的旅程,函数inner的万能参数接收到a和b打包,然后inner函数充当中间商将打包后的元组给了f,在f中打散又成了变量a和b,在装饰器时就不会影响传参了,这就是装饰带参数的函数

装饰有返回值的函数

def wrapper(f):
def inner():
ret = f()
return ret
return inner
@wrapper
def func():
return('我不管,我最帅')

哈哈,这段代码中有我的心声,你们都懂的,很简单,装饰有返回值的参数,在inner函数中将f()赋值给ret,这样ret就接收到了返回值,再将ret返回给inner(),以此来达到“模拟”被装饰函数的返回值,也可以说是通过这种方法来拿到被装饰函数的返回值。

好,到此对Python装饰器应该有那么一丢丢的认识了哈,我不管,就得有认识。下面的内容和文章关系不大哈

第一篇正经写的文章,可能文章内容表达不尽如人意的正经哈,但初心是好的,就是分享知识,分享心得嘛,嗯,不管怎么说,我还是很欣慰的对自己,哈哈,能有人从中有收获就更perfect喽

版权声明:本文为muchengQ原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/muchengQ/p/11078760.html