python cookbook 学习系列(一) python中的装饰器
简介
装饰器本质上是一个Python函数,它可以让其他函数在不需要做任何代码变动的前提下增加额外功能,装饰器的返回值也是一个函数对象。它经常用于有切面需求的场景,比如:插入日志、性能测试、事务处理、缓存、权限校验等场景。装饰器是解决这类问题的绝佳设计,有了装饰器,我们就可以抽离出大量与函数功能本身无关的雷同代码并继续重用。概括的讲,装饰器的作用就是为已经存在的对象添加额外的功能,我们也称之为AOP(面向切面编程)
原理
实现装饰器的最主要的原因是python中一切皆为对象,我们会把方法看做一个对象包装起来
实现
首相,我们先来看一个简单的例子,有一个add方法:

def add(x, y): print('result is {}'.format(x + y))
现在有一个新的需求,我们想在这个方法执行完之后print一句话证明他执行成功了,同样我们又不想修改这个add方法,那我们可以新建一个方法:
def printres(func): func() print('Done') printres(add)
那这样是ok的。但是这样的话,我们每次都要将一个函数作为参数传递给printres函数。而且这种方式已经破坏了原有的代码逻辑结构,之前执行业务逻辑时,执行运行add(),但是现在不得不改成printres(add)。那么有没有更好的方式的呢?当然有,答案就是装饰器。我就直接贴代码:

# coding=utf-8 """ 学习装饰器 2016-08-20 by oldman """ from functools import wraps """ 先来看一个简单的装饰器 """ def decor1(func): @wraps(func) def wrapper(*args, **kwargs): func(*args, **kwargs) print('i am a decorate') return wrapper @decor1 def add(x, y): print('result is {}'.format(x + y)) # if __name__ =="__main__": # add(2,3) """ 再来看一个带参数的装饰器 """ def decor2(parm): """ parm为装饰器用到的参数 """ def _decor2(func): # func为被装饰的函数 @wraps(func) # wraps 装饰器会把func的元数据带过来 def wrapper(*args, **kwargs): if parm: func(*args, **kwargs) print('I am true') else: print('sorry, false') return wrapper return _decor2 @decor2(True) # 这里装饰器的参数为True def add1(x, y): print('result is {}'.format(x + y)) if __name__ == '__main__': add1(2, 3)
注意到functools.wraps,wraps本身也是一个装饰器,它能把原函数的元信息拷贝到装饰器函数中,这使得装饰器函数也有和原函数一样的元信息了,如果不在装饰器里使用@wrap的话,被装饰的函数的元信息会丢失。
总结
这是一个很好的解决方案,不得不感叹python的灵活,人生苦短,我用python。
参考文章:http://www.zhihu.com/question/26930016
学习交流群 :226704167
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!