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-装饰器的使用详解相关推荐

  1. python装饰器实例-python装饰器实例大详解

    原标题:python装饰器实例大详解 一.作用域 在python中,作用域分为两种:全局作用域和局部作用域. 全局作用域是定义在文件级别的变量,函数名.而局部作用域,则是定义函数内部. 关于作用域,我 ...

  2. python装饰器实例-python装饰器使用实例详解

    这篇文章主要介绍了python装饰器使用实例详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 python装饰器的作用就是在不想改变原函数代码的情 ...

  3. python装饰器详解-python装饰器使用实例详解

    这篇文章主要介绍了python装饰器使用实例详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 python装饰器的作用就是在不想改变原函数代码的情 ...

  4. python装饰器由浅入深_详解Python装饰器由浅入深

    装饰器的功能在很多语言中都有,名字也不尽相同,其实它体现的是一种设计模式,强调的是开放封闭原则,更多的用于后期功能升级而不是编写新的代码.装饰器不光能装饰函数,也能装饰其他的对象,比如类,但通常,我们 ...

  5. Python装饰器执行顺序详解

    探究多个装饰器执行顺序 装饰器是Python用于封装函数或代码的工具,网上可以搜到很多文章可以学习,我在这里要讨论的是多个装饰器执行顺序的一个迷思. 疑问 大部分涉及多个装饰器装饰的函数调用顺序时都会 ...

  6. python装饰器详解51-python装饰器使用实例详解

    这篇文章主要介绍了python装饰器使用实例详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 python装饰器的作用就是在不想改变原函数代码的情 ...

  7. python类装饰器详解-Python类装饰器实现方法详解

    本文实例讲述了Python类装饰器.分享给大家供大家参考,具体如下: 编写类装饰器 类装饰器类似于函数装饰器的概念,但它应用于类,它们可以用于管理类自身,或者用来拦截实例创建调用以管理实例. 单体类 ...

  8. python函数装饰器详解_Python语言函数装饰器用法实例详解

    这篇文章主要介绍了Python语言函数装饰器用法,以实例形式较为详细的分析了Python函数装饰器的常见使用技巧,需要的朋友可以参考下,希望对大家学习Python语言有所帮助. 本文实例讲述了pyth ...

  9. python基础篇大合集,进程、装饰器、列表详解篇!

    进程以及状态 1. 进程 2. 进程的状态 进程的创建-multiprocessing 1. 创建进程 2. 进程pid 3. Process语法结构如下 4. 给子进程指定的函数传递参数 5. 进程 ...

  10. python基础篇大合集,进程、装饰器、列表详解篇

    1. 进程 程序:例如xxx.py这是程序,是一个静态的 进程:一个程序运行起来后,代码+用到的资源 称之为进程,它是操作系统分配资源的基本单元. 不仅可以通过线程完成多任务,进程也是可以的 2. 进 ...

最新文章

  1. 词向量到Bert代码——部分习题
  2. matlab 天线设计 泰勒加权_微带天线设计尺寸MATLAB编程及其仿真验证
  3. mysql 之mvcc多版本控制
  4. 【NLP】Transformer温故知新
  5. c/c++程序员的技术栈
  6. OpenCASCADE:拓扑 API之3D模型Defeaturing
  7. python内存池机制_python的内存管理机制
  8. 疫情相关电信诈骗涉案金额超3.51亿元,谨防这四类骗局!
  9. 平均聚类系数_Python聚类算法的应用实例
  10. java中的原型模式_java中的原型模式理解
  11. php date()
  12. 苹果x来电闪光灯怎么设置_免费设置来电视频彩铃,安卓苹果都适用!
  13. 蒙特卡洛仿真的基于Python实例
  14. SpringBoot 教程核心功能-Web 开发(请求处理)
  15. Android 远程协助(亲情助手||投屏||远程演示)实现思路和简单实现
  16. 随笔--初到青岛,爱意油然而生
  17. MATLAB中的偏最小二乘回归(PLSR)和主成分回归(PCR)
  18. 数据库的实例化操作——员工信息的查询——简单表查询(二)
  19. 26.K-均值算法的优化目标、随机初始化、聚类数的选择
  20. 【Cesium】计算模型的朝向四元数,实现模型运动中调整朝向

热门文章

  1. python+turtle制作一个生日蛋糕
  2. 电脑如何修改关闭显示器和休眠时间
  3. 树莓派安装ubuntu 20.04后配置wifi固定ip地址
  4. Java程序员从笨鸟到菜鸟之(序言)+全部链接
  5. 基于MODIS数据的滁州市冬小麦长势遥感监测研究
  6. 实现悬浮球的桌面显示
  7. 1、synchronized、Lock、volatile
  8. 锂电池充电的同时也能放电吗?
  9. 小程序图表wx-chart
  10. 缩小Abaqus结果文件的方法