python-装饰器的使用详解
1 装饰器的定义及调用
装饰器格式如下:
def decorator(func):def wrapper():...func()...return wrapper
装饰器的调用
@装饰器名称
def func():pass
来看一个例子
# 定义装饰器
def decorator(func):def wrapper():func()print('画眉毛')return wrapper# 调用装饰器
@decorator
def face():print('我是一张脸,我现在素颜')face()'''运行结果:
我是一张脸,我现在素颜
画眉毛
'''
2 装饰器的运行流程
# 定义装饰器
def decorator(func):print('wrapper执行前')def wrapper():func()print(f'func地址:{func}')print('画眉毛')print('wrapper执行后')print(f'wrapper地址:{wrapper}','\n')return wrapper# 调用装饰器
@decorator
def face():print('我是一张脸,我现在素颜')print(f'face地址:{face}','\n')face()
运行结果:
wrapper执行前
wrapper执行后
wrapper地址:<function decorator.<locals>.wrapper at 0x00000000027D89D8> face地址:<function decorator.<locals>.wrapper at 0x00000000027D89D8> 我是一张脸,我现在素颜
func地址:<function face at 0x00000000027D8950>
画眉毛
步骤1:def decorator()
定义decorator函数,并给函数decorator分配内存空间,但不执行decorator函数
步骤2:@decorator
1、将face作为参数传递给装饰器decorator --> decorator(face)
2、执行decorator函数–> 进入步骤3
步骤3:进入decorator函数体执行
1、print(‘wrapper执行前’)
2、def wrapper():定义wrapper函数,并给wrapper函数分配内存空间,但不执行wrapper函数
3、print(‘wrapper执行后’)
4、print(f’wrapper地址:{wrapper}’)
5、return wrapper --> 此时return wrapper对象给被装饰器修饰的函数 face,即face==wrapper
6、步骤3执行完毕,步骤3执行结果如下
wrapper执行前
wrapper执行后
wrapper地址:<function decorator.<locals>.wrapper at 0x00000000028389D8>
7、进入步骤4
步骤4:print(f’face地址:{face}’)
运行结果如下
face地址:<function decorator.<locals>.wrapper at 0x00000000028389D8>
以上可以看出被decorator装饰的face地址==wrapper地址
步骤5:face()
–> 此时face就是wrapper,则此时执行wrapper函数 --> 步骤6
步骤6:wrapper()
1、func() --> 即执行函数face
2、print(f’func地址:{func}’)
3、print(‘画眉毛’)
4、步骤6执行结果如下:
我是一张脸,我现在素颜
func地址:<function face at 0x0000000002838950>
画眉毛
此时全部执行完毕
3 被装饰的函数带参数
装饰器万能公式:被装饰函数可不带参数,可带1个参数,可带多个参数
def decorator(func):def wrapper(*args,**kwargs):......func(*args,**kwargs)......return wrapper
例子来啦
def decorator(func):def wrapper(*args,**kwargs):print('登陆中....')sleep(1)print('登陆成功.....')func(*args,**kwargs)return wrapper# 被装饰函数不带参数
@decorator
def f():print('f---> 我要买东西\n')
f()# 被装饰函数带1个参数
@decorator
def f1(x):print(f'f1---> {x}颗糖加入购物车\n')
f1(3)# 被装饰函数带1个列表参数
@decorator
def f2(list1):for item in list1:print(f'f2---> 把{item}加入购物车')
f2(['苹果','橘子'])# 被装饰函数带多个参数
@decorator
def f3(x,name='yy'):print(f'f3---> 给{name}买{x}个橘子')
f3(2,name='ww')
运行结果:
登陆中....
登陆成功.....
f---> 我要买东西登陆中....
登陆成功.....
f1---> 3颗糖加入购物车登陆中....
登陆成功.....
f2---> 把苹果加入购物车
f2---> 把橘子加入购物车
登陆中....
登陆成功.....
f3---> 给ww买2个橘子
4 装饰器带参数
装饰器带参数,我们要用到3层装饰器:
from time import sleepdef outer(n): # 第一层:接收装饰器的参数def decorator(func): # 第二层:接收被装饰函数def wrapper(*args,**kwargs): # 接收被装饰函数的参数print(f'等待{n}s登陆')sleep(n)print('登陆成功.....')func(*args,**kwargs)return wrapper # 返回第三层函数名return decorator # 返回第二层函数名@outer(2)
def f():print('我要买东西')
f()
运行结果:
等待2s登陆
登陆成功.....
我要买东西
5 多层装饰器
# 装饰器1
def decorator1(func):print(f'd1.func:{func}')print('d1 start')def wrapper(*args,**kwargs):func(*args,**kwargs)print('d1 ---> 画眉毛')print(f'd1.wrapper:{wrapper}')print('d1 end\n')return wrapper# 装饰器2
def decorator2(func):print(f'd2.func:{func}')print('d2 start')def wrapper(*args, **kwargs):func(*args,**kwargs)print ('d2 ---> 涂口红')print(f'd2.wrapper:{wrapper}')print('d2 end\n')return wrapper# 先用靠近函数的decorator1,再用decorator2
@decorator2
@decorator1
def face():print('我是脸')print(f'face:{face}','\n')face()
运行结果:
d1.func:<function face at 0x00000000027F89D8>
d1 start
d1.wrapper:<function decorator1.<locals>.wrapper at 0x00000000027F8A60>
d1 endd2.func:<function decorator1.<locals>.wrapper at 0x00000000027F8A60>
d2 start
d2.wrapper:<function decorator2.<locals>.wrapper at 0x00000000027F8AE8>
d2 endface:<function decorator2.<locals>.wrapper at 0x00000000027F8AE8> 我是脸
d1 ---> 画眉毛
d2 ---> 涂口红
总结 为什么使用装饰器
我们现在有A、B两个项目,1个函数 func
1、项目A、B都有多处地方要调用func,如上图调用即可
2、现在项目A在调用func的同时,还想要func做更多的动作,但B只想要func原本的功能。我们该怎么做?
方案1:修改func的内容,使他满足A项目的要求
缺点:导致B项目在调用func时做了不想要的动作
方案2:新增一个func_new 供A项目调用
缺点:A项目中多处调用func的地方都要一个个修改成调用 func_new,显然不建议使用
方案3:使用装饰器
1、A在调用func前,使用装饰器decorator装饰func后再调用func:装饰器中是A想要func额外要的功能
2、B仍然调用原始func
优点:无需修改A、B中的任何代码,只需新定义一个装饰器,在A调用func时用装饰器修饰func即可
python-装饰器的使用详解相关推荐
- python装饰器实例-python装饰器实例大详解
原标题:python装饰器实例大详解 一.作用域 在python中,作用域分为两种:全局作用域和局部作用域. 全局作用域是定义在文件级别的变量,函数名.而局部作用域,则是定义函数内部. 关于作用域,我 ...
- python装饰器实例-python装饰器使用实例详解
这篇文章主要介绍了python装饰器使用实例详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 python装饰器的作用就是在不想改变原函数代码的情 ...
- python装饰器详解-python装饰器使用实例详解
这篇文章主要介绍了python装饰器使用实例详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 python装饰器的作用就是在不想改变原函数代码的情 ...
- python装饰器由浅入深_详解Python装饰器由浅入深
装饰器的功能在很多语言中都有,名字也不尽相同,其实它体现的是一种设计模式,强调的是开放封闭原则,更多的用于后期功能升级而不是编写新的代码.装饰器不光能装饰函数,也能装饰其他的对象,比如类,但通常,我们 ...
- Python装饰器执行顺序详解
探究多个装饰器执行顺序 装饰器是Python用于封装函数或代码的工具,网上可以搜到很多文章可以学习,我在这里要讨论的是多个装饰器执行顺序的一个迷思. 疑问 大部分涉及多个装饰器装饰的函数调用顺序时都会 ...
- python装饰器详解51-python装饰器使用实例详解
这篇文章主要介绍了python装饰器使用实例详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 python装饰器的作用就是在不想改变原函数代码的情 ...
- python类装饰器详解-Python类装饰器实现方法详解
本文实例讲述了Python类装饰器.分享给大家供大家参考,具体如下: 编写类装饰器 类装饰器类似于函数装饰器的概念,但它应用于类,它们可以用于管理类自身,或者用来拦截实例创建调用以管理实例. 单体类 ...
- python函数装饰器详解_Python语言函数装饰器用法实例详解
这篇文章主要介绍了Python语言函数装饰器用法,以实例形式较为详细的分析了Python函数装饰器的常见使用技巧,需要的朋友可以参考下,希望对大家学习Python语言有所帮助. 本文实例讲述了pyth ...
- python基础篇大合集,进程、装饰器、列表详解篇!
进程以及状态 1. 进程 2. 进程的状态 进程的创建-multiprocessing 1. 创建进程 2. 进程pid 3. Process语法结构如下 4. 给子进程指定的函数传递参数 5. 进程 ...
- python基础篇大合集,进程、装饰器、列表详解篇
1. 进程 程序:例如xxx.py这是程序,是一个静态的 进程:一个程序运行起来后,代码+用到的资源 称之为进程,它是操作系统分配资源的基本单元. 不仅可以通过线程完成多任务,进程也是可以的 2. 进 ...
最新文章
- 词向量到Bert代码——部分习题
- matlab 天线设计 泰勒加权_微带天线设计尺寸MATLAB编程及其仿真验证
- mysql 之mvcc多版本控制
- 【NLP】Transformer温故知新
- c/c++程序员的技术栈
- OpenCASCADE:拓扑 API之3D模型Defeaturing
- python内存池机制_python的内存管理机制
- 疫情相关电信诈骗涉案金额超3.51亿元,谨防这四类骗局!
- 平均聚类系数_Python聚类算法的应用实例
- java中的原型模式_java中的原型模式理解
- php date()
- 苹果x来电闪光灯怎么设置_免费设置来电视频彩铃,安卓苹果都适用!
- 蒙特卡洛仿真的基于Python实例
- SpringBoot 教程核心功能-Web 开发(请求处理)
- Android 远程协助(亲情助手||投屏||远程演示)实现思路和简单实现
- 随笔--初到青岛,爱意油然而生
- MATLAB中的偏最小二乘回归(PLSR)和主成分回归(PCR)
- 数据库的实例化操作——员工信息的查询——简单表查询(二)
- 26.K-均值算法的优化目标、随机初始化、聚类数的选择
- 【Cesium】计算模型的朝向四元数,实现模型运动中调整朝向