Python 装饰器学习以及实际使用场景实践
前几天在看Flask框架,,不是非常的理解,回来补装饰器的功课。阅读很多的关于装饰器的文章,自己整理一下,适合自己的思路的方法和例子,与大家分享。
app = Flask(__name__) @app.route("/") def hello(): return "Hello World!"
1、装饰器是什么
装饰器是Python语言中的高级语法。主要的功能是对一个函数、方法、或者类进行加工,作用是为已经存在的对象添加额外的功能,提升代码的可读性。
装饰器是设计模式的一种,被用于有切面需求的场景,较为经典的有插入日志、性能测试、事务处理等
2、装饰器的语法
装饰器的语法如下:
当前Python的装饰器语法如下:
装饰器可以用def的形式来定义。装饰器接收一个可调用对象作为输入参数,并返回一个新的可调用对象。
装饰器新建了一个可调用对象,也就是return 返回的函数funx,在新增的函数中,可以添加我们需要的功能,并通过调用原有函数来实现原有函数的功能。
3、装饰器的使用
3.1不带参数的装饰器
定义装饰器非常的简单:
def deco(func): """无参数调用decorator声明时必须有一个参数,这个参数将接收要装饰的方法""" print "before myfunc() called." func() print "after myfunc() called." return func @deco def myfunc(): print " myfunc() called." myfunc() myfunc()
定义好装饰器后,,,即可使用。上面这个装饰器在使用的时候有一个问题,即只在第一次被调用,并且原来的函数多执行一次。执行输出如下:
before myfunc() called. myfunc() called. after myfunc() called. myfunc() called. --函数多执行一次的输出 myfunc() called. --第二次调用,装饰器不生效
要保证新函数每次被调用,使用下面的方法来定义装饰器
def deco(func): """无参数调用decorator声明时必须有一个参数,这个参数将接收要装饰的方法""" def _deco(): print "before myfunc() called." func() print "after myfunc() called." #return func 不需要返回func retrun _deco @deco def myfunc(): print " myfunc() called." return OK myfunc() myfunc()
函数输出如下:
before myfunc() called. myfunc() called. after myfunc() called. before myfunc() called. myfunc() called. after myfunc() called.
这样可以看到,装饰器每次都得到了调用。
3.2带参数的函数进行装饰器
def deco(func): def _deco(a, b): print("before myfunc() called.") ret = func(a, b) print(" after myfunc() called. result: %s" % ret) return ret return _deco @deco def myfunc(a, b): print(" myfunc(%s,%s) called." % (a, b)) return a + b myfunc(1, 2) myfunc(3, 4)
输出:
before myfunc() called. myfunc() called. After myfunc() called. result: 3 before myfunc() called. myfunc() called. After myfunc() called. result: 7
内嵌函数的形参和返回值与原函数相同,装饰函数返回内嵌包装函数。
3.3装饰器带参数
def decoWithArgs(arg): """由于有参数的decorator函数在调用时只会使用应用时的参数而不接收被装饰的函数做为参数, 所以必须返回一个decorator函数, 由它对被装饰的函数进行封装处理""" def newDeco(func): #定义一个新的decorator函数 def replaceFunc(): #在decorator函数里面再定义一个内嵌函数,由它封装具体的操作 print "Enter decorator %s" %arg #进行额外操作 return func() #对被装饰函数进行调用 return replaceFunc return newDeco #返回一个新的decorator函数 @decoWithArgs("demo") def MyFunc(): #应用@decoWithArgs修饰的方法 print "Enter MyFunc" MyFunc() #调用被装饰的函数
输出:
nter decorator demo
Enter MyFunc
这个情形适用于原来的函数没有参数,新增加打印的情况。常见适用的地方是增加函数的打印日志。
3.4对参数数量不确定的函数进行装饰
下面的例子是一个邮件异步发送的例子,函数的参数数据部确定,装饰器实现了对于邮件发送函数的异步发送。
from threading import Thread def async(f): def wrapper(*args, **kwargs): thr = Thread(target = f, args = args, kwargs = kwargs) thr.start() return wrapper @async def send_async_email(msg): mail.send(msg) def send_email(subject, sender, recipients, text_body, html_body): msg = Message(subject, sender = sender, recipients = recipients) msg.body = text_body msg.html = html_body send_async_email(msg)
并且这个装饰器可以适用一切需要异步处理的功能,做到非常好的代码复用。
3.5让装饰器带类参数
def __deco(): print("before %s called [%s]." % (func.__name__, cls)) cls.acquire() try: return func() finally: cls.release() return __deco return _deco @deco(locker) def myfunc(): print(" myfunc() called.") myfunc() myfunc()
输出为:
before myfunc called [__main__.locker]. locker.acquire() called.(this is staticmethon) myfunc() called. locker.release() called.(dot need object ) before myfunc called [__main__.locker]. locker.acquire() called.(this is staticmethon) myfunc() called. locker.release() called.(dot need object )
装饰器总结
当我们对某个方法应用了装饰方法后, 其实就改变了被装饰函数名称所引用的函数代码块入口点,使其重新指向了由装饰方法所返回的函数入口点。由此我们可以用decorator改变某个原有函数的功能,添加各种操作,或者完全改变原有实现。
作者:Stitch
来源:51CTO
python学习之路-装饰器的使用 开发者学堂课程,了解Python语言的基本特性、编程环境的搭建、语法基础、算法基础等,了解Python的基本数据结构,对Python的网络编程与Web开发技术具备初步的知识,了解常用开发框架的基本特性,以及Python爬虫的基础知识。 课程地址:https://developer.aliyun.com/learning/course/601/detail/8739
python学习之路-闭包 开发者学堂课程,了解Python语言的基本特性、编程环境的搭建、语法基础、算法基础等,了解Python的基本数据结构,对Python的网络编程与Web开发技术具备初步的知识,了解常用开发框架的基本特性,以及Python爬虫的基础知识。 课程地址:https://developer.aliyun.com/learning/course/601/detail/8737
python学习之路- sort 开发者学堂课程,了解Python语言的基本特性、编程环境的搭建、语法基础、算法基础等,了解Python的基本数据结构,对Python的网络编程与Web开发技术具备初步的知识,了解常用开发框架的基本特性,以及Python爬虫的基础知识。 课程地址:https://developer.aliyun.com/learning/course/601/detail/8736
python学习之路-递归 简介: 开发者学堂课程,了解Python语言的基本特性、编程环境的搭建、语法基础、算法基础等,了解Python的基本数据结构,对Python的网络编程与Web开发技术具备初步的知识,了解常用开发框架的基本特性,以及Python爬虫的基础知识。 课程地址:https://developer.aliyun.com/learning/course/601/detail/8731
python学习之路-命名空间 开发者学堂课程,了解Python语言的基本特性、编程环境的搭建、语法基础、算法基础等,了解Python的基本数据结构,对Python的网络编程与Web开发技术具备初步的知识,了解常用开发框架的基本特性,以及Python爬虫的基础知识。 课程地址:https://developer.aliyun.com/learning/course/601/detail/8731
相关文章
- 简明 Python 教程学习笔记_2_函数
- python 利用Scipy计算person 和spearman相关系数
- 【Python学习实践教程】10个Python经典项目实战,练手必备
- 零基础学习Python之数据分析一
- 为什么转行比较喜欢选择学习Python编程?
- 零基础入门Python之后,学习结束后找什么工作?工资多少?
- Python 数据结构之元组
- 5招教你用Python构建好玩的深度学习应用
- python tensorflow 学习
- Ubuntu 16.04 python和OpenCV安装
- python学习之去除字符串中的空格(6种方法)
- 萌新学习Python爬取B站弹幕+R语言分词demo说明
- Python机器学习零基础理解逻辑回归分析
- Python教程大全之使用 Python 轻松创建词云的初学者指南(教程含源码)
- (转)利用Auto ARIMA构建高性能时间序列模型(附Python和R代码)
- 《从问题到程序:用Python学编程和计算》——练习
- Python实例---游戏人生[类的学习]
- Python学习---Python下[set集合]的学习
- 华为OD机试 - 分积木(Python) | 机试题+算法思路+考点+代码解析 【2023】
- python学习(一)之Pycharm安装与配置
- python odoo word模板上下标问题
- python爬虫学习(二):定向爬虫例子-->使用BeautifulSoup爬取"软科中国最好大学排名-生源质量排名2018",并把结果写进txt文件
- 学习笔记(29):Python网络编程&并发编程-信号量
- 【机器学习】SVM理论与python实践系列
- 机器学习之支持向量机SVM之python实现ROC曲线绘制(二分类和多分类)