一.定义

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

二.简单类的装饰器

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

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

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

上面代码块为:

#给每个类打印一句话

def Decorator(obj):

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

return obj

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

class School():

pass

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

代码块如下:

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

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__)

三.高级类的装饰器

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

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

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

该部分代码块如下:

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

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),当时就猜测到,是利用的装饰器来完成该功能。那么到底是怎么实现的呢?见下文:

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

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

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

至此,该部分的功能已经完全实现。这就是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)

python装饰器类-python_类装饰器相关推荐

  1. Python 闭包、单个装饰器、多个装饰器、装饰器修饰类、应用场景

    1. 闭包 在 Python 中,函数也可以作为参数.我们可以执行下面的代码: def func(a, b):return a + bprint(func) 我们直接输出函数名,而没有加括号.输出结果 ...

  2. python类装饰器详解-Python类中的装饰器在当前类中的声明与调用详解

    我的Python环境:3.7 在Python类里声明一个装饰器,并在这个类里调用这个装饰器. 代码如下: class Test(): xx = False def __init__(self): pa ...

  3. Python基础(八)--迭代,生成器,装饰器与元类

    目录 Python基础(八)--迭代,生成器,装饰器与元类 1 迭代 1.1 可迭代对象与迭代器 1.2 自定义迭代类型 1.3 迭代合体 2 生成器 2.1 什么是生成器 2.2 生成器表达式 2. ...

  4. Python中的property类和@property装饰器

    Python中的property类和@property装饰器 在Python的类中,为了避免使用者直接在类的外部操作属性和方法,我们可以将属性和方法设置成私有属性和私有方法. 如果我们需要访问私有属性 ...

  5. python装饰器class_PYTHON里的装饰器能装饰类吗

    展开全部 Python 装饰2113器装饰类中的方法 目前在中文网上能5261搜索到的绝大部分关于4102装饰器的教程,都在讲如何装饰一个1653普通的函数.本文介绍如何使用Python的装饰器装饰一 ...

  6. Python:闭包(简介、使用方法、nonlocal修改闭包内使用的外部变量)、装饰器(定义、作用、通用装饰器、多个装饰器、带参数的装饰器、类装饰器、装饰器方式添加WEB框架的路由)

    一.闭包的介绍 闭包可以保存函数内的变量 当闭包执行完毕,外部函数的变量才释放. # 闭包的作用:可以保存外部函数的变量 # 闭包的形成条件 # 1.函数嵌套 # 2.内部函数使用了外部函数的变量或者 ...

  7. python︱函数、for、if、_name_、迭代器、防范报错、类定义、装饰器、argparse模块、yield

    新手入门python,开始写一些简单函数,慢慢来,加油~ 文章目录 一.函数 +三个内建函数filter,map和reduce + if 1.def/lambda 2.if 如果if + for列表的 ...

  8. Python 函数(类)的装饰器与闭包

    2019独角兽企业重金招聘Python工程师标准>>> 装饰器是在函数调用上的修饰.这些修饰仅是当声明一个函数或者方法的时候,才会应用的额外调用. 装饰器的语法看起来像是这个样子: ...

  9. 兄弟连学python(06)装饰器:对类或者函数进行功能的扩展

    #第一步,基本函数 ''' def hulk(): print("酒逢知己饮,诗向会人吟!") #调用函数 hulk() #第二步 扩展函数功能(不能修改原函数) #用于扩展基本函 ...

最新文章

  1. 有耐心就能学好Linux
  2. 算法系列15天速成——第十天 栈
  3. .ini文件的读写操作
  4. STM32F4 HAL库开发 -- SPI Flash
  5. OpenCV实现图像对齐ECC算法(附完整代码)
  6. 类中调用界面ActiveX控件报错当前线程不在单线程单元中因此无法实例化 ActiveX 控件的解决办法...
  7. 深入理解javascript原型链
  8. 哎呀你不要把他叫出来_不吼不叫,学会这3个亲子互动方法,孩子不专注都难...
  9. git 源代码自动检查_Visual Studio中Git的简单使用
  10. 【Elasticsearch】不常用 length filer、ngram filter、trim filter、truncate filter、unique filter、synonym token
  11. Too many input arguments.
  12. STM32 使用DMA+DAC+TIMER 输出正弦波
  13. 5006.推荐初学者几本CCNA教程和材料
  14. 以云服务器产品为例,深度分析比对华为云、阿里云、腾讯云
  15. 【Windows】无法访问指定设备,路径或文件,您可能没有合适的权限访问这个项目
  16. 百度谷歌一起搜 - 百Google度 - Chrome插件2
  17. 鸿蒙第3批升级名单,鸿蒙系统首批升级名单详细介绍
  18. 堡垒机的主要功能是什么?为什么需要堡垒机?
  19. STM32-ADC-信号调理电路校准-excel-matlab
  20. 罗永浩二次直播遇冷,用户到底想要什么样的直播 ?

热门文章

  1. NewSQL——优化的SQL存储引擎(TokuDB, MemSQL)+?
  2. centos 自动挂载磁盘
  3. 2019.7.15随笔
  4. bat给文件追加换行内容
  5. 腾讯的模板引擎---artTemplate
  6. 数据库还原失败System.Data.SqlClient.SqlError: 无法执行 BACKUP LOG,因为当前没有数据库备份...
  7. hdu 5167 bfs
  8. ubuntu14.04配置中文latex完美环境(texlive+texmaker+lyx)
  9. 在MVVM实践中的Command与CommandParameter的使用
  10. 随机数---等概率,特殊概率