<p >
<p ><p >这样做逻辑上是没问题的,功能是实现了,但是我们调用的时候不再是调用真正的业务逻辑today函数,而是换成了logging_tool函数,这就破坏了原有的代码结构,为了支持日志功能,原有代码需要大幅修改,那么有没有更好的方式的呢?当然有,答案就是装饰器。<p >二、开天辟地<p >一个简单的装饰器<p ><p >以上也是装饰器的原理!!!<p >三、Pythonic世界的初探<p >@语法糖 接触 Python 有一段时间的话,对 @ 符号一定不陌生了,没错 @ 符号就是装饰器的语法糖,它放在函数开始定义的地方,这样就可以省略最后一步再次赋值的 *** 作<p ><p >有了 @ ,我们就可以省去today = logging_tool(today)这一句了,直接调用 today() 即可得到想要的结果。 不需要对today() 函数做任何修改,只需在定义的地方加上装饰器 ,调用的时候还是和以前一样。 如果我们有其他的类似函数,可以继续调用装饰器来修饰函数 ,而不用重复修改函数或者增加新的封装。这样,提高程序可重复利用性,并增加程序的可读性。<p >装饰器在 Python 使用之所以如此方便,归因于 Python函数能像普通的对象一样能作为参数传递给其他函数,可以被赋值给其他变量,可以作为返回值,可以被定义在另外一个函数内。<p ><p ><p >2、让装饰器同时支持带参数或不带参数<p ><p >如上所示,参数有两种类型,一种是字符串,另一种是可调用的函数类型。因此,通过对参数类型的判断即可实现支持带参数和不带参数的两种情况。<p >3、类装饰器<p >装饰器不仅可以是函数,还可以是类,相比函数装饰器,类装饰器具有灵活度大、高内聚、封装性等优点。使用类装饰器主要依靠类的call方法,当使用 @ 形式将装饰器附加到函数上时,就会调用此方法。<p >(1)示例一、被装饰函数不带参数<p ><p >(3)示例三、不依赖初始化函数,单独使用call函数实现(体现类装饰器灵活性大、高内聚、封装性高的特点) 实现当一些重要函数执行时,打印日志到一个文件中,同时发送一个通知给用户<p ><p >进一步扩展,给LogTool创建子类,来添加email的功能:<p ><p >4、装饰函数 -> 装饰类<p >(1)函数层面的装饰器很常见,以一个函数作为输入,返回一个新的函数; (2)类层面的装饰其实也类似,已一个类作为输入,返回一个新的类;<p >例如:给一个已有的类添加长度属性和getter、setter方法<p ><p >五、上古神器<p >1、@property -> getter/setter方法<p >示例:给一个Student添加score属性的getter、setter方法<p ><p >2、@classmethod、@staticmethod<p >(1)@classmethod 类方法:定义备选构造器,第一个参数是类本身(参数名不限制,一般用cls) (2)@staticmethod 静态方法:跟类关系紧密的函数<p >简单原理示例:<p ><p >3、@functools.wraps<p >装饰器极大地复用了代码,但它有一个缺点:因为返回的是嵌套的函数对象wrapper,不是原函数,导致原函数的元信息丢失,比如函数的docstring、 <span >name 、参数列表等信息。不过呢,办法总比困难多,我们可以通过@functools.wraps将原函数的元信息拷贝到装饰器里面的func函数中,使得装饰器里面的func和原函数有一样的元信息。<p ><p >@functools.wraps让我们可以通过属性wrapped直接访问被装饰的函数,同时让被装饰函数正确暴露底层的参数签名信息<pre >countdown.wrapped(1000) # 访问被装饰的函数print(inspect.signature(countdown)) # 输出被装饰函数的签名信息<p >4、Easter egg<p >(1) 定义一个接受参数的包装器<pre >@decorator(x,y,z)def func(a,b):pass<p >等价于<pre >func = decorator(x,z)(func)<p >即:decorator(x,z)的返回结果必须是一个可调用的对象,它接受一个函数作为参数并包装它。<p >(2)一个函数可以同时定义多个装饰器,比如:<p ><p >欢迎关注我的博客或者公众号:https://home.cnblogs.com/u/Python1234/ Python学习交流 总结以上是内存溢出为你收集整理的Python装饰器的前世今生!全部内容,希望文章能够帮你解决Python装饰器的前世今生!所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)