装饰器说明Python中的装饰器是一种可以装饰其它对象的工具。

该工具本质上是一个可调用的对象(callable),所以装饰器一般可以由函数、类来实现。

装饰器本身需要接受一个被装饰的对象作为参数,该参数通常为函数、方法、类等对象。

装饰器需要返回一个对象,该对象可以是 经过处理的原参数对象、一个包装且类似原参数的对象;或者返回一个不相干内容(通常不建议使用)。

下面我们就结合代码来理解Python中的装饰器。

装饰器分类

最简单的装饰器

这就是最简单的装饰器,并且是一个没有任何用处的装饰器。但是它确实是一个装饰器,并且可以用的很好。比如:

而上面使用了装饰器的代码,其实我们可以通过其它方式达到相同的效果。具体见下:

所以通过最简单的代码,我们可以发现装饰器其实就是接受了一个函数(对象),并且返回了一个函数(对象)的函数(可调用对象)。

用于修改对象的装饰器

在理解了装饰器的含义之后,再来看一个稍微有点作用的装饰器。代码如下:

这个装饰器在上一个例子的基础上,只添加了一行代码,但是却有了实际的作用。它的作用就是给被装饰的对象,添加一个name属性并且设置值为python。这个装饰器的使用效果如下:

可以看到实际的使用过程中,warp装饰器已经成功的给Bar对象添加了name属性。除了给类对象添加属性之外,它还可以给函数对象添加属性。

用于模拟对象的装饰器--函数装饰器

上面例子中的装饰器,是直接修改了传入对象;而装饰器最常用的方式却是模拟一个传入对象。即返回一个和原对象相似的对象(即调用接口完全一样的另一个对象),并且该模拟对象是包装了原对象在内的。具体代码如下:

上面是一个函数装饰器,即用来修饰函数的装饰器。因为它返回了一个模拟func对象的inner对象。而这里inner对象是一个函数,所以这个装饰器只能装饰函数。(因为inner对象只能模拟func这样的函数对象,不能模拟class对象)

上述代码中最后一行foo(),其实质上是执行的inner()。为了证明这一点,我们可以在inner中打印一条信息。并查看下foo的__name__属性。

上述代码执行后的结果如下:

可以看到首先打印的是 foo.__name__代码,注意内容是inner而不是foo(说明其本质上是inner函数);其次打印的时候,先打印inner函数中的内容,后打印foo函数中的内容。

用于模拟对象的装饰器--类方法装饰器

与函数装饰器类似的还有类方法装饰器,其作用相同,格式相近。只是些微有些区别,下面就是类方法装饰器的代码。

可以看到类方法装饰器和函数装饰器,唯一的区别就是多了一个默认的self参数;这是因为类方法本身就比函数多这么一个参数。其执行的结果如下:

所以最后一行代码zoo.zoo函数执行的其实是inner函数。

用于模拟对象的装饰器--类装饰器

装饰器除了可以装饰函数、方法之外,还可以装饰器类对象。具体的代码如下:

通过代码可以看出,类装饰器与函数装饰器类似。即模拟一个与原参数接口一致的类对象。所以对于模拟类的装饰器,只能用在其可以模拟的对象之上,并不能互相修饰其它类型的对象。

特殊应用的装饰器

上面都是比较常规的装饰器,python中还有另外一些特殊的装饰器。比如:类静态属性装饰器。比如下面的代码:

上述代码中的@property装饰器就是一个特殊的装饰器,它把ratio方法变成了一个属性。从最后一句调用代码可以看出,使用的是foo.ratio而不是foo.ratio()。

对于这类装饰器需要Python的特定属性和机制的支持才可以实现,不同特性的装饰器所需机制不同。如上述代码中的@property装饰器就可以使用下面的代码来实现。

具体的使用效果如下:

可以看到效果和原生的@property装饰器是一样的。

类实现的装饰器

在之前对于装饰器的说明中,有说道装饰器是一个callable对象。除了函数可以实现装饰器之外,还可以通过类来实现。那么类实现装饰器的具体代码如下:

这个类装饰器实现的功能,也是给传入的对象添加name属性,并设置其值为warp。其调用效果如下:

装饰带参数/返回值的对象

前面列举的所有例子,被装饰的对象都是无参数的。如果你需要装饰一个带参数的对象。那么就需要相应的修改下装饰器代码了。注意:这里特指那些模拟类型的装饰器。即函数装饰器、类方法装饰器、类装饰器。

假设我们先有一个带参数的函数,其内容如下:

def add(x, y):

return x * y

如果使用原来的函数装饰器,肯定就会出错。主要因为这个函数带参数,并且也有返回值。而原来的函数装饰器则不能支持,原函数装饰器如下:

这样的函数装饰器就可以装饰add函数了。因为inner函数添加了x,y参数,调用func对象时也添加了参数,并且返回了func对象的返回值。具体使用效果如下:

装饰器带参数

上面说到的是被修饰的对象带参数的情况,还有一种情况就是装饰器本身希望支持带参数。这种情况类似于函数模块通过带参数可以更加灵活的道理一样。通过给装饰器带上参数,可以使得装饰器的功能更加的灵活。代码如下:

装饰器应用

Python装饰器的应用比较广泛,大部分场景的公共处理逻辑都可以使用装饰器去简化。(使用上类似于JAVA中的注解)一般比较常见的场景比如:日志记录

权限验证

单例模式

竞争资源管理

python装饰器类型错误_Python各种类型装饰器?一起看看这份详解说明吧相关推荐

  1. python grpc unary call错误_python的黑魔法-装饰器

    python的装饰器 装饰器 简单的来说就是函数的函数,在执行目标函数时,先执行装饰器函数,很像HOOk 简单的装饰器 实现一个打印日志的装饰器 def myLogger(func):def wrap ...

  2. python定义数组并赋值_python中的数组赋值与拷贝的区别详解

    具体的注解我已经写在了程序里面:通俗的解释了python里面的浅拷贝与深拷贝的不同,请看程序. # -*- coding: utf-8 -*- import numpy as np import co ...

  3. python处理列表中字典_Python 列表、元组、字典及集合操作详解

    一.列表 列表是Python中最基本的数据结构,是最常用的Python数据类型,列表的数据项不需要具有相同的类型 列表是一种有序的集合,可以随时添加和删除其中的元素 列表的索引从0开始 1.创建列表 ...

  4. python table数据抓取_Python爬虫:数据抓取工具及类库详解

    前言 文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 作者: ncepu_Chen PS:如有需要Python学习资料的小伙伴可以 ...

  5. python调用c++动态库_Python应用:调用C/C++动态链接库的方法详解

    Linux系统下调用动态库(.so) 1.linuxany.c代码如下: #include "stdio.h" void display(char* msg){ printf(&q ...

  6. python爬取论文代码_Python selenium爬取微信公众号文章代码详解

    需求: 想阅读微信公众号历史文章,但是每次找回看得地方不方便. 思路: 1.使用selenium打开微信公众号历史文章,并滚动刷新到最底部,获取到所有历史文章urls. 2.对urls进行遍历访问,并 ...

  7. python模块cv2人脸识别_Python基于Opencv来快速实现人脸识别过程详解(完整版)

    前言 随着人工智能的日益火热,计算机视觉领域发展迅速,尤其在人脸识别或物体检测方向更为广泛,今天就为大家带来最基础的人脸识别基础,从一个个函数开始走进这个奥妙的世界. 首先看一下本实验需要的数据集,为 ...

  8. python读取excel写入数据库_python实现读取excel写入mysql的小工具详解

    Python是数据分析的强大利器 利用Python做数据分析,第一步就是学习如何读取日常工作中产生各种excel报表并存入数据中,方便后续数据处理. 这里向大家分享python如何读取excel,并使 ...

  9. python创建进程的方法_python进程的状态、创建及使用方法详解

    本文实例讲述了python进程的状态.创建及使用方法.分享给大家供大家参考,具体如下: 进程以及状态 1. 进程 程序:例如xxx.py这是程序,是一个静态的 进程:一个程序运行起来后,代码+用到的资 ...

最新文章

  1. mysql 无法登陆_MySQL root用户无法登录原因及解决办法
  2. priority_queue 结构体的优先级设置
  3. HP存储raid5两块硬盘离线lvm下vxfs文件系统恢复数据过程
  4. String.slice和String.substring有什么区别?
  5. (仿头条APP项目)8.新闻详情页面实现和butterknife插件使用
  6. java面试题十三 string创建了几个对象
  7. php获取ip写到文本,php 文本转HTML与获取IP函数
  8. java 队列 array_Java源码解析阻塞队列ArrayBlockingQueue常用方法
  9. 测试Flex代码覆盖率工具---FlexCover
  10. Java面试题分享,这份资料包你值得拥有!
  11. 用垃圾建设台湾海峡陆桥的主意是否可行
  12. keil_v4 安装(图文教程)
  13. Unity 实现 角色的换装
  14. 博弈论python实例_博弈论读书笔记(七)贝叶斯博弈举例和显示原理
  15. 二维码条形码生成打印软件C#源码,根据变量自动添加抬头
  16. 镜像服务器有什么作用,镜像文件、镜像服务器是什么意思
  17. python第三方库matplotlib绘制简单折线图
  18. 靠股票能改变普通人命运吗?
  19. java添加zip并下载,java - 使用java创建zip并使其可下载。 - SO中文参考 - www.soinside.com...
  20. DSP/BIOS详解入门-再回炉

热门文章

  1. linux智能灌溉流程,农田自动灌溉系统及灌溉方法与流程
  2. orbslam算法框架
  3. UVA - 207 PGA Tour Prize Money
  4. Oracle数据库表解锁语句
  5. EditText控件常用属性
  6. SQL语句汇总(一)——数据库与表的操作以及创建约束
  7. ArcSDE服务入门
  8. asp.net mvc(八)
  9. 初学者python笔记(内置函数_1)
  10. 淮北计算机考试报名,淮北2019年12月计算机等级考试报名入口/注意事项