python装饰器类-python_类装饰器

一.定义

装饰器就是一个给对象添加额外功能的函数,其本质是函数。它的基本构造:高阶函数+函数嵌套+闭包。基础知识讲解详见:https://blog.51cto.com/10836356/2095118

二.简单类的装饰器

我们先看简单的类的装饰器,如果我们需要给任意一个类添加一个打印功能,即:没当操作这个类时,就打印”定义了一个装饰类函数”,见下图:

watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=

@Decorator #相当于执行 School = Decorator(School)

注释内容若有疑问,请参考:https://blog.51cto.com/10836356/2095118

上面代码块为:

#给每个类打印一句话

def Decorator(obj):

print("定义了一个装饰器函数")

return obj

@Decorator #相当于执行 School = Decorator(School)

class School():

pass

如果我们要给该类添加一个数据属性和一个函数属性,又该如何定义这个装饰器呢?见下图:

watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=

代码块如下:

#给每个类添加一个数据属性和一个函数属性

def Decorator(obj):# print(School.__dict__)

#添加数据属性

obj.addr = "浙江省杭州市"

def price():

pass

#添加函数属性

obj.price = price

return obj

@Decorator #相当于执行 School = Decorator(School)

class School():

def __init__(self,name,price):

self.name =name

self.price =price

#打印类的属性字典

print(School.__dict__)

三.高级类的装饰器

此时,在实际场景中可能需要在装饰器中使用变量参数,那么该如何实现呢?

在二中只利用了装饰器中的高阶函数的概念,要实现上述的需求,就需要使用装饰器构造的另外两部分:函数嵌套、闭包。如下图所示,我们需要给类添加一个数据属性,但是此时不同的类要求添加的属性是可变的,处理方法见下图:

watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=

多个类使用该装饰器添加不同的属性,如下图:

watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=

该部分代码块如下:

#给每个类添加一个可变的数据属性

def Decorator(**kwargs):

def add(obj):

"添加数据属性"

# print('调用外部函数的**kwargs',kwargs)

for key,val in kwargs.items():

# 添加数据属性

setattr(obj,key,val)

return obj

# print("外部传入的参数为:",kwargs)

return add

@Decorator(addr = "浙江省杭州市",name ="浙江大学") #执行顺序:1.运行Decorator函数,先打印外部的传入的参数,返回add函数名;2.再执行School = add(School)

class School():

def __init__(self,price):

self.price =price

@Decorator(addr = "湖北省",price =12000)

class School1():

pass

print(School.__dict__)

print(School1.__dict__)

四.类的装饰器在实际中的应用

我们在学习类时,介绍了类的静态属性(参考https://blog.51cto.com/10836356/2108790),当时就猜测到,是利用的装饰器来完成该功能。那么到底是怎么实现的呢?见下文:

watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=

在上面的代码中,静态属性的属性是由python内部自己给我们实现的,那么到底它是怎么工作的呢?见下图:

watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=

此时我们还未进行实例化及调用类的静态属性,见下图:

watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=

我们可以看到,当进行实例化时,并没有明显差异,但是当调用类的total方法时,就会去调用Myproperty类中的get()方法(此处用到的是描述符优先级的知识,将另开篇幅讲解,此处直接应用),为达到理想的效果,我们只需在get()中进行处理就好,如下图进一步处理:

watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=

至此,该部分的功能已经完全实现。这就是python在为我们做的工作。那么我们已经理解了原理,这样我们就可以自定义类的其他装饰器。

该部分代码块如下:

class Myproperty():

def __init__(self,fun):

# print("执行Myproperty类的构造方法") #调用Myproperty类时会首先运行它

self.fun = fun

def __get__(self, instance, owner):

"""

:param instance: 代表school实例本身

:param owner: 代表类School本身

:return:

"""

# print('调用Myproperty的属性时将执行此方法')

return self.fun(instance)

class School():

"""

@name:学校名字

@addr:学校地址

@price:学费

@num:招生人数

"""

def __init__(self,name,addr,price,num):

self.name =name

self.addr =addr

self.price =price

self.num =num

# @property

@Myproperty #等价于-->>total=Myproperty(total)

def total(self):

"求总的学费"

return self.price*self.num

school = School('浙江大学','浙江省杭州市',12000,6000)

print(school.total)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值