当前位置: 首页 > news >正文

Python多个装饰器的顺序 转载

3、使用两个装饰器
当一个装饰器不够用的话,我们就可以用两个装饰器,当然理解起来也就更复杂了,当使用两个装饰器的话,首先将函数与内层装饰器结合然后在与外层装饰器相结合,要理解@语法的时候到底执行了什么,是理解装饰器的关键。这里还是用最简单的例子来进行说明。

 1 def outer2(func2):
 2     def inner2(*args,**kwargs):
 3         print('开始')
 4         r=func2(*args,**kwargs)
 5         print('结束')
 6         return r
 7     return inner2
 8  
 9 def outer1(func1):
10     def inner1(*args,**kwargs):
11         print('start')
12         r=func1(*args,**kwargs)
13         print('end')
14         return r
15     return inner1
16  
17 @outer2                                # 这里相当于执行了 f=outer1(f)  f=outer2(f),步骤如下
18 @outer1                                #1、f=outer1(f) f被重新赋值为outer1(1)的返回值inner1,
19 def f():                               #    此时func1为 f():print('f 函数')
20     print('f 函数')                     #2、f=outer2(f) 类似f=outer2(inner1) f被重新赋值为outer2的返回值inner2
21                                        #    此时func2 为inner1函数 inner1里面func1函数为原来的 f():print('f 函数')
22                                                                           
23 f()                                    # 相当于执行 outer2(inner1)()
24 
25 #执行结果如下:
26 开始                                   # 在outer函数里面执行,首先打印 ‘开始 ’
27 start                                 # 执行func2 即执行inner1函数 打印 ‘start’
28 f 函数                                 # 在inner1函数里面执行 func1 即f()函数,打印 ‘f 函数’
29 end                                   # f函数执行完,接着执行inner1函数里面的 print('end')
30 结束                                   # 最后执行inner2函数里面的 print('结束')

 

python执行代码的时候碰到两个装饰器解释过程:

1、将@outer1和f()先执行:函数outer1()将返回值inner1重新赋值给f,此时f指向的函数体是inner1的函数体,这里称f为新f

2、执行@outer:@outer2将新f当作参数传入inner2(),然后将返回值inner2重新赋值给f,此时f指向的函数体是inner2的函数体

执行过程和解释过程是相反的:从上到下的,先通过第一层@outer2 -----> @outer1 -------> f(),结合执行结果你就很明白了。

转载于:https://www.cnblogs.com/eric_yi/p/7249661.html

相关文章:

  • springboot使用Thymedef模板引擎环境配置
  • Linux系统的pxe自动化运维部署
  • ftp--pureftpd1.0.46
  • 深入JVM分析spring-boot应用hibernate-validator
  • 正确的Kado ED「永遠のこたえ」
  • 最简单的基于FFmpeg的移动端样例:IOS 视频解码器
  • python全栈开发从入门到放弃之递归函数的调用
  • 选好网络管理工具 “0掉线”也并非不可能
  • 大数据市场蕴含万亿级别巨大商机
  • HBase – Memstore Flush深度解析
  • 什么是工程师文化?
  • 大数据将颠覆润滑管理模式
  • 重磅!2017大数据十大趋势
  • 高效数据中心网络管理五大技巧
  • 首席数据官如何养成?
  • 【跃迁之路】【519天】程序员高效学习方法论探索系列(实验阶段276-2018.07.09)...
  • ES6核心特性
  • Java面向对象及其三大特征
  • java小心机(3)| 浅析finalize()
  • linux安装openssl、swoole等扩展的具体步骤
  • mysql_config not found
  • nfs客户端进程变D,延伸linux的lock
  • python学习笔记 - ThreadLocal
  • vue的全局变量和全局拦截请求器
  • 对话 CTO〡听神策数据 CTO 曹犟描绘数据分析行业的无限可能
  • 构建工具 - 收藏集 - 掘金
  • 关于springcloud Gateway中的限流
  • 回流、重绘及其优化
  • 前端 CSS : 5# 纯 CSS 实现24小时超市
  • 前端技术周刊 2018-12-10:前端自动化测试
  • 嵌入式文件系统
  • 腾讯优测优分享 | 你是否体验过Android手机插入耳机后仍外放的尴尬?
  • 协程
  • 优化 Vue 项目编译文件大小
  • MiKTeX could not find the script engine ‘perl.exe‘ which is required to execute ‘latexmk‘.
  • ​猴子吃桃问题:每天都吃了前一天剩下的一半多一个。
  • ​如何在iOS手机上查看应用日志
  • (HAL库版)freeRTOS移植STMF103
  • (阿里巴巴 dubbo,有数据库,可执行 )dubbo zookeeper spring demo
  • (附源码)spring boot球鞋文化交流论坛 毕业设计 141436
  • (附源码)ssm基于微信小程序的疫苗管理系统 毕业设计 092354
  • (每日持续更新)jdk api之FileFilter基础、应用、实战
  • (十七)Flask之大型项目目录结构示例【二扣蓝图】
  • (五)IO流之ByteArrayInput/OutputStream
  • (转)jQuery 基础
  • ../depcomp: line 571: exec: g++: not found
  • .mysql secret在哪_MYSQL基本操作(上)
  • .NET CF命令行调试器MDbg入门(一)
  • .net framwork4.6操作MySQL报错Character set ‘utf8mb3‘ is not supported 解决方法
  • .NET 实现 NTFS 文件系统的硬链接 mklink /J(Junction)
  • /run/containerd/containerd.sock connect: connection refused
  • :中兴通讯为何成功
  • @Query中countQuery的介绍
  • @TableLogic注解说明,以及对增删改查的影响
  • [ linux ] linux 命令英文全称及解释