Python装饰器的实现和万能装饰器

在Python中,装饰器是在不改变已有函数的代码的前提下,给函数增加新的功能的一种函数。

装饰器接收一个函数作为参数,返回值也是一个函数。

在Python中,实现装饰器的方式叫做闭包。

一、闭包的实现

闭包是指函数中定义了一个内函数,内函数里运用了外函数的临时变量,并且外函数的返回值是内函数的引用。

闭包的使用,可以隐藏内部函数的工作细节,只给外部使用者提供一个可以执行的内部函数的引用。

# 闭包
def outer_func():a = 1def inner_func(b):nonlocal aa += bprint(a)return areturn inner_funcfunc = outer_func()
func(100)print(outer_func()(1000))

运行结果:

101
1001
1001

闭包的重点:

1.外函数的内部定义了一个内函数

2.内部函数使用了外部函数的临时变量

3.外函数的返回值是内函数的引用

在上面的代码中,外函数是outer_func,在他的内部有内函数inner_func,a是外函数的临时变量,在内函数中使用了a,外函数的返回值是内函数inner_func。

如果在内部函数中直接使用外部函数的变量a时,不改变a的值,直接使用就可以了,如果要修改a的值,需要将变量声明为 nonlocal。

内部函数可以接收参数,然后在内函数里使用参数。

使用func接收outer_func()的返回值,返回的值func是一个函数,相当于inner_func,给func()传入参数并执行,则会运行inner_func中的代码。

也可以不使用变量来接收,而是直接在outer_func()后面直接传参和执行,后面有两个小括号:outer_func()(),第二个括号中传入内函数的参数。

二、装饰器实现及使用

def func_name(func):def wrapper(*args, **kwargs):print("func name is {}".format(func.__name__))return func(*args, **kwargs)return wrapper@func_name
def func_one():print('this is function one')@func_name
def func_two():print('this is function two')func_one()
func_two()

运行结果:

func name is func_one
this is function one
func name is func_two
this is function two

装饰器是通过闭包的方式实现的,外函数接收一个函数作为外函数的临时变量,然后在内函数中执行这个函数。

内函数将需要的参数接收进来并传给执行的函数,然后将执行结果返回。在内函数中,可以添加额外的功能的代码,这些额外的功能就是装饰器添加的功能。

最后外函数将内函数返回。

使用装饰器来装饰函数时,在被装饰的函数的前一行,使用 @装饰器函数名 形式来装饰,则函数的本身的功能正常实现,装饰器中添加的功能也实现了。如上面代码中打印被装饰函数的函数名。

三、多个装饰器同时装饰一个函数

def decorator_one(func):def wrapper(*args, **kwargs):print('decorator one start')result = func(*args, **kwargs)print('decorator one end')return resultreturn wrapperdef decorator_two(func):def wrapper(*args, **kwargs):print('decorator two start')result = func(*args, **kwargs)print('decorator two end')return resultreturn wrapper@decorator_two
@decorator_one
def hello_python():print('Hello Python!')hello_python()

运行结果:

decorator two start
decorator one start
Hello Python!
decorator one end
decorator two end

可以看到,当多个装饰器装饰同一个函数时,会是一个嵌套的装饰结果,也就是说,先执行完离函数近的一个装饰器,然后再用离函数远的装饰器来装饰执行结果。

四、万能装饰器

装饰器的外函数会接收一个函数作为参数,这个函数在内函数内部执行,这个函数可以有参数也可以没有参数,可以有返回值也可以没有返回值。

所以装饰器也分为四类,无参无返回值、无参有返回值、有参无返回值、有参有返回值。是否有参数和返回值完全取决于被装饰的函数。

但是,我们写装饰器的目的就是用一个装饰器来装饰不同的函数,所以要考虑装饰器的通用性。我们通过可变参数来实现一种可以用来装饰任何函数的装饰器,万能装饰器。

def decorator_all(func):def wrapper(*args, **kwargs):print('add some coding')return func(*args, **kwargs)return wrapper

使用这种装饰器,可以用来装饰任意函数,不管函数是否有参数,是否有返回值。

五、类装饰器

在Python中,也可以通过类的方式来实现装饰器,通过使用 __init__ 和 __call__方法来实现。

class DecoratorClass(object):def __init__(self, func):self._func = funcdef __call__(self, *args, **kwargs):print('class decorator')return self._func(*args, **kwargs)@DecoratorClass
def func_three():print('this is function three')func_three()

运行结果:

class decorator
this is function three

在实现类装饰器的时候,使用__init__()方法来接收被装饰函数,使用__call__()方法来添加装饰器要实现的功能,并在__call__()方法中执行和返回被装饰函数。

Python装饰器的实现和万能装饰器相关推荐

  1. 恒星播放器 1.101中文版(万能视频播放器)

    恒星播放器 mac中文版是mac上一款超级好用的万能视频播放器,可以迅速播放各种格式的视频和音频,而且不损失播放质量,为您提供流畅舒适的高清视频播放体验! 支持所有格式视频播放 播放所有格式视频文件 ...

  2. 怎么彻底卸载html5播放器,爱奇艺万能播放器卸载不了怎么办? 彻底删除爱奇艺万能播放器的教程...

    随着各类软件数量的增加,一些厂家或广告商为了更大范围的占领市场,会采取一些极端方法在用户的电脑中安装自己的软件.普通用户在上网或者安装其它软件的过程中,往往就会不知不觉的被安装了一些不想要的软件,而且 ...

  3. 操作简单的影音文件播放工具-万能播放器下载

    万能播放器是一款操作简单的影音文件播放工具,小伙伴们可以使用万能播放器播放喜欢的影音文件.万能播放器可支持p2p在线点播.边看边下.防病毒等功能.万能播放器几乎兼容市面上所有视频格式,有喜欢的小伙伴们 ...

  4. 如何写一个Python万能装饰器,既可以装饰有参数的方法,也可以装饰无参数方法,或者有无返回值都可以装饰

    需求:定义一个装饰器,既可以装饰有参数的方法,又可以装饰没有参数的方法,既可以装饰有返回值的方法,又可以装饰没有返回值的方法 代码如下: def decorate(test): #定义一个装饰器函数d ...

  5. Python:从requests请求重试到万能重试装饰器

    今天来介绍下Python中从requests请求重试到万能重试装饰器. 从requests请求重试到万能重试装饰器 重试,在编写代码的过程中,是一个很常见的需求. 比如: 请求重试(例如:超时) 文件 ...

  6. python万能装饰器实现计算函数的调用次数和执行时间

    直接上代码 # python万能装饰器实现计算函数的调用次数和执行时间 import timedef set_fun(func):num = 0 # 初始化次数def call_fun(*args, ...

  7. python描述器做权限控制_Python装饰器14-描述器

    描述器 这是Python一个重要的概念,英文名:Descriptor descriptor是对象的一个属性,只不过它存在于类的dict中并且有特殊方法get(可能还有set和__delete)而具有一 ...

  8. python 装饰器实现事件绑定_Python装饰器是怎么实现的?

    Python中的装饰器是通过利用了函数特性的闭包实现的,所以在讲装饰器之前,我们需要先了解函数特性,以及闭包是怎么利用了函数特性的 ① 函数特性 python中的函数特性总的来说有以下四点: 1. 函 ...

  9. python进阶(小白也能看懂)——装饰器浅谈(一)

    python进阶(小白也能看懂)--装饰器(一) 第四篇 文章目录 python进阶(小白也能看懂)--装饰器(一) 1.函数基础知识 例子1.1 例子1.2 例子1.3 例子1.4 2.不带参数的装 ...

最新文章

  1. python 如何查看模块所有方法-Python 查看模块的帮助文档,方法和帮助信息
  2. day02: SQL_DML, oracle中sql的各种查询
  3. 【学习小记】一般图最大匹配——带花树算法
  4. 安卓隐藏摄像_侧置摄像与隐藏前摄,拒绝单调乏味,这两款国产5G手机独具匠心...
  5. php-cgi.exe系统错误 无法启动程序,因为计算机中丢失api-ms-win-crt-conio-l1-1-0.dll 尝试解决安装该程序以解决此问题
  6. Android的Window类详解
  7. 关于 Hibernate 中的“脏数据”、“脏对象”
  8. 2021福州地区高考成绩排名查询,2021年福州各高中高考成绩排名及放榜最新消息...
  9. 腾讯2012实习生招聘面试题:矩阵中A移动到B一共有多少走法
  10. Matlab中一个很有用的函数:regionprops
  11. ASP.NET验证控件之RegularExpressionValidator
  12. Windows下 Nginx创建文件服务器
  13. Rust的审核团队突然宣布集体辞职
  14. 动态生成表格案例(HTML+CSS+JS)
  15. Python---Excel文件xls格式转为xlsx格式
  16. sql注入(三)绕过方法及防御手段
  17. python 提取 B 站视频中的音频
  18. 基于PLC控制四自由度气动式机械手设计
  19. 【生活】空调工作原理及基本操作
  20. QQ软件已被破坏或部分文件丢失

热门文章

  1. 抓到的一次suse11 xen用libvirt连接的错误
  2. android 9 patch
  3. 用区块链保护共享数据?存储初创公司Gospel开始试水
  4. 多链路及服务器负载均衡原理与设备构建方案
  5. ICallbackEventHandler不支持二次回调的问题
  6. 如何防止网页Demo被那些赖账的客户盗用
  7. Nodejs线上日志部署
  8. UiPath实践经验总结(二)
  9. C#基础知识1-深入理解值类型和引用类型
  10. 函数式编程 -- 测试题集