理解python中装饰器的作用


Posted in Python onJuly 21, 2021

装饰器的作用就是用一个新函数封装旧函数(是旧函数代码不变的情况下增加功能)然后会返回一个新函数,新函数就叫做装饰器,一般为了简化装饰器会用语法糖@新函数来简化

例子:

这是一段代码,但功能太少,要对这个进行增强,但又不能改变代码。

def hello():
    return "hello world!"

现在我们的需求是要增强hello()函数的功能,希望给返回加上HTML标签,比如<i>hello world</i>,但要求我们不得改变hello()函数原来的定义。

def makeitalic(fun):#makitalic传了一个新函数
    def wrapped():#内部函数
        return "<i>"+fun()+"</i>"#要加的新功能
    return wrapped#返回的是wrapped函数功能

def hello():#对这个功能进行增强
    return "hello world!"
#makeitalic里面传入了hello函数,然后内部函数fun()函数也就相当于hello函数了
hello_2=makeitalic(hello)
#打印新函数,返回的就是<i>hello world!</i>
print(hello_2())

为了增强原函数hello的功能,定义了一个函数,它接收原函数作为参数,并返回一个新的函数,在这个返回的函数中,执行了原函数,并对原函数的功能进行了增强。

事实上,makeitalic就是一个装饰器(decorator),它封装了原函数hello,并返回了一个新函数,用于增强原函数的功能,并将其赋值给hello。

一般情况下,我们使用装饰器提供的@语法糖(Syntactic Sugar),来简化上面的操作。

####使用@语法糖
def makeitalic(fun):
    def wrapped():
        return "<i>" + fun() + "</i>"
    return wrapped

@makeitalic#使用了装饰器可以直接调用,不需要赋值了
def hello():
    return "hello world"
print(hello())#使用了装饰器可以直接调用,不需要赋值了

像上面的情况,可以动态的修改函数(或类的)功能的函数就是装饰器。本质上,它是一个高阶函数,以被装饰的函数(比如上面的hello)为参数,并返回一个包装后的函数(比如上面的wrapped)给被修饰函数(hello)。

当调用hello()函数时,hello函数的执行流程如下分析:

1.把hello函数作为参数传给@符号后面的装饰器函数。

2.然后开始执行装饰器函数,并返回一个包装了的函数,同时,改变原函数的指向,现在原函数指向了这个包装函数。

3.执行原函数,其实此时执行的是包装了的函数,所以说,装饰器增强了一个现有函数的功能,但不会改变现有函数的定义。

普通装饰器的使用形式:

@decorator
def fun():
 pass

#格式就如同下面的:

def fun():
 pass
fun = decorator(fun)#不使用语法糖要进行赋值

装饰器可以定义多个,离函数定义最近的装饰器最先被调用,比如:

@decotator_one
@decorator_two
def fun():
 pass

#格式如同下面的:

def fun():
 pass
fun = decorator_one(decorator_two(fun))

装饰器还可以带参数,比如:

@decorator(arg1, arg2)
def fun():
 pass

#格式如同下面的:

def fun():
 pass
fun = decorator(arg1, arg2)(fun)

到此这篇关于python中装饰器的作用的文章就介绍到这了,更多相关python装饰器作用内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
在Python的Django框架中用流响应生成CSV文件的教程
May 02 Python
Python多进程分块读取超大文件的方法
Apr 13 Python
python获取txt文件词向量过程详解
Jul 05 Python
python实现数据分析与建模
Jul 11 Python
Python3 pandas 操作列表实例详解
Sep 23 Python
使用 Supervisor 监控 Python3 进程方式
Dec 05 Python
Python验证码截取识别代码实例
May 16 Python
Django自关联实现多级联动查询实例
May 19 Python
Keras:Unet网络实现多类语义分割方式
Jun 11 Python
基于Keras 循环训练模型跑数据时内存泄漏的解决方式
Jun 11 Python
python 可视化库PyG2Plot的使用
Jan 21 Python
Python使用永中文档转换服务
May 06 Python
opencv检测动态物体的实现
Python爬虫中urllib3与urllib的区别是什么
python Django框架快速入门教程(后台管理)
Python编写nmap扫描工具
Jul 21 #Python
Django模型层实现多表关系创建和多表操作
Jul 21 #Python
Python基本数据类型之字符串str
Jul 21 #Python
Python中22个万用公式的小结
Jul 21 #Python
You might like
PHP 强制下载文件代码
2010/10/24 PHP
简单谈谈PHP中的Reload操作
2016/12/12 PHP
Laravel中的chunk组块结果集处理与注意问题
2018/08/15 PHP
国外Lightbox v2.03.3 最新版 下载
2007/10/17 Javascript
JavaScript更改class和id的方法
2008/10/10 Javascript
写出高效jquery代码的19条指南
2014/03/19 Javascript
jquery插件之定时查询待处理任务数量
2014/05/01 Javascript
JavaScript知识点总结(十六)之Javascript闭包(Closure)代码详解
2016/05/31 Javascript
js 获取元素所有兄弟节点的实现方法
2016/09/06 Javascript
JQuery和HTML5 Canvas实现弹幕效果
2017/01/04 Javascript
JavaScript 函数的定义-调用、注意事项
2017/04/16 Javascript
详解express与koa中间件模式对比
2017/08/07 Javascript
JS路由跳转的简单实现代码
2017/09/21 Javascript
React 高阶组件入门介绍
2018/01/11 Javascript
微信小程序实现发红包功能
2018/07/11 Javascript
详解nvm管理多版本node踩坑
2019/07/26 Javascript
使用vuex存储用户信息到localStorage的实例
2019/11/11 Javascript
JS中数组实现代码(倒序遍历数组,数组连接字符串)
2019/12/29 Javascript
[04:53]DOTA2英雄基础教程 祈求者
2014/01/03 DOTA
[03:26]《DAC最前线》之EG经理自述DOTA2经历
2015/02/02 DOTA
[10:05]DOTA2-DPC中国联赛 正赛 iG vs PSG.LGD 选手采访
2021/03/11 DOTA
python定时采集摄像头图像上传ftp服务器功能实现
2013/12/23 Python
Python打包可执行文件的方法详解
2016/09/19 Python
Python3 搭建Qt5 环境的方法示例
2020/07/16 Python
Python django框架 web端视频加密的实例详解
2020/11/20 Python
python SOCKET编程基础入门
2021/02/27 Python
详解基于canvas的视频遮罩插件
2018/01/04 HTML / CSS
美国体育用品在线:Modell’s Sporting Goods
2018/06/07 全球购物
优秀毕业生求职推荐信范文
2013/11/21 职场文书
英语道歉信范文
2014/01/09 职场文书
三个儿子教学反思
2014/02/03 职场文书
店铺转让协议书(2014版)
2014/09/23 职场文书
纪检干部个人对照检查材料
2014/09/23 职场文书
保安2014年终工作总结
2014/12/06 职场文书
培训班通知
2015/04/25 职场文书
六一儿童节新闻稿
2015/07/17 职场文书