python进阶:搞懂装饰器和切面编程
学习目标:
装饰器、切面编程,实际使用体会。
纸上学来终觉浅
装饰器和切面编程:
常见的函数,我们一般的返回值一个常见的数值或者列表,比如:
def mysum(a,b):return a + b
result = mysum(1,2)
print(result)
mysum函数返回的是整数1+2的值,为3.
但是python神奇的地方就是,函数的返回值,可以是另一个函数。比如:
def mysum_log():print('input two number for sum ')def mysum(a,b):return a + breturn mysum
mysum2= mysum_log()
print(mysum2(1,2))
这样,mysum_log的函数值是一个函数,赋给了变量mysum2,然后print直接用mysum2(1,2)就可以运行函数.此时的mysum2函数有点类似于mysum的功能,但是增加了print功能。
运行结果:
input two number for sum
3
我们其实可以把变量mysum2直接改成mysum,改一下名字而已,结果就有点神奇了:
def mysum_log():print('input two number for sum ')def mysum(a,b):return a + breturn mysum
mysum= mysum_log()
print(mysum(1,2))
这样我们看起来像调用了mysum函数,但实际上我们还多了打印日志的print功能。业界成这个叫闭包–鬼知道为啥要叫这么个名字,还以为包pi有关。
这有什么用呢?单纯看没啥用,但是当这个mysum方式最初是别人写的,而且别人不愿意改他的函数,可以通过这种方式丰富函数的功能。
举个例子,隔壁老王写了个函数:
def laowangsum(a, b):return a ^ 2 + b ^ 2
laowangsum的功能是求平方和,但是没有解释,会让人产生误解,你叫老王修改函数,增加注释,他懒不愿意动,怎么办?
此时你想到能不能偷梁换柱,帮他增加点注释,让你的函数调用laowangsum会添加注释log。于是:
def laowangsum(a, b):return a ^ 2 + b ^ 2def mysum_log():print('老王写的sum函数,实际是两个数平方和 ')return laowangsumlaowangsum = mysum_log()
print(laowangsum(1, 2))
你调用的laowangsum函数,实际上多运行了你的注释,偷偷改了老王的函数的功能。这个是闭包的作用。
另一个需求:我们要求对每个函数都打印出日志信息,以便于错误时定位是哪个函数出了问题。或者进行函数大屏监控,怎么办?
为每个函数都加入一个写log的代码?重复性太高,我们想办法抽象起来,既然闭包可以改变函数功能,那用闭包就可以实现,但是现在的闭包需要写明具体函数,不可能以后新增一个函数都去改一下闭包函数。此时就需要装饰器,也叫切面编程。简单来讲,我把一个代表函数的变量传进闭包函数,然后这个闭包函数就可以自适应传进去的函数,自动调用它,不用每次新增函数都去修改闭包,只用调用一次闭包函数即可。
import functoolsdef log_decorator(function):@functools.wraps(function)def wrapper(*args,**kwargs):print('log begin')function(*args,**kwargs)print('log end')return wrapper
比如老王的函数定义时,加上一个@log_decorator,就可以自动帮他写日志,他不用管日志这块:
import functoolsdef log_decorator(function):@functools.wraps(function)def wrapper(*args,**kwargs):print('log begin')result = function(*args,**kwargs)print('log end')return resultreturn wrapper@log_decorator
def laowangsum(a, b):return a ^ 2 + b ^ 2print(laowangsum(1, 2))
运行结果:
log begin
log end
7
可以看到老王虽然自己只实现了加法逻辑,但是函数运行时,却自动多了写日志的功能,就像函数被砍了两刀,自动加上了写log的功能一样。所以叫切面编程。
而且用print(laowangsum.name)打印出来,laowangsum确实就是老王自己定义的函数,名字没有变化,没有被偷梁换柱,因为是@functools.wraps(function)的原因。
装饰类:
除了函数,还可以用装饰类,大同小异。把函数替换成类
class log:def __init__(self,func):self.func = funcself.num_calls = 0 #函数调用次数def __call__(self, *args, **kwargs):self.num_calls += 1print('number of calls is :{}'.format(self.num_calls))return self.func(*args, **kwargs)@log
def example():print('I am being called')example()
example()
example()
结果:
number of calls is :1
I am being called
number of calls is :2
I am being called
number of calls is :3
I am being called
log类自动帮助统计了函数被调用次数。
结论:
装饰器经常用在:
1、 写日志
2、统计运行时间
3、 校验输入数据的有效性和用户认证等
python进阶:搞懂装饰器和切面编程相关推荐
- Python 进阶_闭包 装饰器
目录 目录 闭包 函数的实质和属性 闭包有什么好处 小结 装饰器 更加深入的看看装饰器的执行过程 带参数的装饰器 装饰器的叠加 小结 装饰器能解决什么问题 小结 闭包 Closure: 如果内层函数引 ...
- 【python进阶】_装饰器
装饰器本身是一个函数. 需求:在下面返回时间的函数前面都在开头加上:当地时间 import time def getXXXTime():print()return time.strftime('%Y_ ...
- 设计模式系列:搞懂装饰器模式,增加自身技能
装饰器模式的定义:指在不改变原有对象的基础上,动态地给该对象增加一些额外的功能的模式,属于对象结构型模式. 装饰器模式的核心在于类的扩展,通过装饰器模式可以透明且动态的扩展类的功能. 装饰器模式的结构 ...
- 一篇文搞懂《AOP面向切面编程》是一种什么样的体验?
写在前面 hello,大家好,我是灰小猿,一个超会写bug的程序猿! 近期一直在准备秋招和技术,所以写文的频率有些下降,但是这也依然阻挡不了我要和大家一起分享技术的热情呀. 之前在专栏<SSM编 ...
- python进阶(小白也能看懂)——装饰器浅谈(一)
python进阶(小白也能看懂)--装饰器(一) 第四篇 文章目录 python进阶(小白也能看懂)--装饰器(一) 1.函数基础知识 例子1.1 例子1.2 例子1.3 例子1.4 2.不带参数的装 ...
- python重难点之装饰器详解
背景 虽然之前看过装饰器的相关内容,但是今天想起来,一直没有好好总结一下,所以特地记录下关于装饰器的一系列用法. 要想理解装饰器首先要明确颇python中的三个概念: 1.一切函数皆为对象 2.高阶函 ...
- python装饰器与闭包_python中闭包和装饰器的理解(关于python中闭包和装饰器解释最好的文章)。...
转载:http://python.jobbole.com/81683/ 呵呵!作为一名教python的老师,我发现学生们基本上一开始很难搞定python的装饰器,也许因为装饰器确实很难懂.搞定装饰器需 ...
- python闭包和装饰器的区别_python中闭包和装饰器的理解(关于python中闭包和装饰器解释最好的文章)。(转)...
呵呵!作为一名教python的老师,我发现学生们基本上一开始很难搞定python的装饰器,也许因为装饰器确实很难懂.搞定装饰器需要你了解一些函数式编程的概念,当然还有理解在python中定义和调用函数 ...
- Python中的decorator装饰器使用方法
装饰器的运用是Python编程中的一项高级技巧,这里由浅入深,整理了12步入门Python中的decorator装饰器使用方法,需要的朋友可以参考下 装饰器(decorator)是一种高级Python ...
最新文章
- SDWAN分支解决方案:sdwan能用于多分支的企业吗?
- HK-2000 数采仪系统说明之 5.H2000SService程序调用说明
- 虚方法(virsual method)
- 冒泡排序法和选择排序法
- 模式串匹配的BF算法和KMP算法
- WEB安全第六篇--千里之外奇袭客户端:XSS和HTML注入
- php缓存技术基础知识
- Dubbo整合Nacos
- c语言pipe函数,pipe 函数 (C语言)
- 分布电容对小信号的干扰解决方案
- HTML5开发工具有哪些?
- Python爬取房价
- 从字节跳动离职后,拿到探探、趣头条、爱奇艺、小红书、15家公司的 offer
- 'PRIMARY' 文件组已满。请删除不需要的文件
- Idaily 知乎日报APP
- NPDP在国内的含金量
- 郑林楷计算机系姚班,郑林楷为什么被清华录取 郑林楷在清华很厉害吗
- 基础贵金属白银技术分析(指标工具篇)
- 【蒸馏+剪枝】(一)Cascaded channel pruning using hierarchical self-distillation
- 如何学python新手入门_如何学习Python,以及新手如何入门?
热门文章
- ensp 查看配置命令
- 电脑显示计算机无法显示,如果计算机无法打开怎么办?
- 微信小程序隐藏滚动条的方法,以及禁止上下滑动的方法
- python中什么是实例-在Python中使用’__rsub__’方法的典型实例是什么?
- java开发环境jdk1.8_linux 搭建 jdk1.8 java开发环境
- JAVA-基础(查找文件夹内文件)
- 魔兽老玩家无需购买《燃烧远征》资料片序列号
- 嵌入式Linux系统运行流程图
- Linux Shell之一 Shell简介
- 【实验】给指定的并且已登陆系统的用户发信息