python 装饰器 参数-Python装饰器(4)带参数的装饰器

2023-05-16

内容纯属个人理解,不对之处,欢迎指正。

之前说过,装饰器其实就是函数,既然是函数,那就可以有参数,装饰器也不例外,接下来我们来分析带参数的装饰器。

如何构造带参数

带参数倒是很简单,在装饰的时候给装饰函数写上参数就行,但是具体的装饰器函数该怎么写,我们需要思考一下。

我们想让它带参数,无非就是对被装饰函数的执行进行一定条件的限定设置,也就是说在函数执行之前,函数就必须具备这个条件,那么这样的话,就有两种选择,要么在传递func以后传递参数;要么在传递func之前传递参数。

在想法上,两种其实是都可以的,但是,我们传递参数的时候是给装饰器传递,也就是说,装饰器函数首先接收的是装饰器函数的参数,然后带着这个参数再去装饰函数。因此,我们就必须先处理装饰器函数的参数,然后再去处理被装饰的函数。

所以在实现上,我们应该这样去构造带参装饰器函数:

def deco_para(parameter):

def deco_func(func):

def wrapper(*args, **kwargs):

print(parameter)

func(*args, **kwargs)

return wrapper

return deco_func

带参装饰器示例

def deco_para(parameter):

print('enter deco_para')

def deco_func(func):

print('enter deco_func')

def wrapper(*args, **kwargs):

print('enter wrapper')

print(parameter)

print('---wrapper: before func---')

func(*args, **kwargs)

print('---wrapper: after func---')

return wrapper

return deco_func

@deco_para(123)

def foo():

print('---foo---')

if __name__ == '__main__':

print('--start--')

foo()

运行结果:

enter deco_para

enter deco_func

--start--

enter wrapper

123

---wrapper: before func---

---foo---

---wrapper: after func---

结果应该不用多说,先接收参数123,然后接收函数foo,最后执行wrapper。

装饰过程解析--多次输出问题

我们解析下过程

deco_func = deco_para(123) # 接收参数123

wrapper = deco_func(foo) # 接收函数foo

foo = wrapper # 重命名

foo() # 执行foo

如果你试着按这个过程去执行代码,会发现一个问题,wrapper函数里面的代码执行了2次。

enter deco_para

enter deco_func

enter deco_para

enter deco_func

enter wrapper

123

---wrapper: before func---

enter wrapper

123

---wrapper: before func---

---foo---

---wrapper: after func---

---wrapper: after func---

我们看下究竟是怎么回事。

# 程序执行,扫面到装饰器,执行装饰器函数内部代码

1.enter deco_para

2.enter deco_func

# deco_para(123)接收参数123时执行3

3.enter deco_para

# deco_func(foo)接收函数foo时执行4

4.enter deco_func

# foo()执行foo()

5.enter wrapper

6.123

7.---wrapper: before func---

8.enter wrapper

9.123

10.---wrapper: before func---

11.---foo---

12.---wrapper: after func---

13.---wrapper: after func---

在之前解析装饰器的时候就提到过,函数被装饰以后,就不是原来的函数了,也就是说上面所执行的foo,其实是wrapper。

那么wrapper里面有什么东西呢?

print('enter wrapper')

print(parameter)

print('---wrapper: before func---')

func(*args, **kwargs)

print('---wrapper: after func---')

似乎执行结果应该是

enter wrapper

123

---wrapper: before func---

---foo---

---wrapper: after func---

但是事实上,此时的wrapper里面的func已经不是原来的func。

回顾闭包:引用了自由变量的函数即是一个闭包,这个被引用的自由变量和这个函数一同存在, 即使已经离开了了创造它的环境也不例外。

那么可以推测,此时的被装饰函数应该具有了额外的东西,这些东西就是

print('enter wrapper')

print(parameter)

print('---wrapper: before func---')

print('---wrapper: after func---')

由此也就可以知道为什么wrapper里面的代码执行了2次:就是在执行到func(*args, **kwargs)的时候,执行了功能丰富以后的func。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

python 装饰器 参数-Python装饰器(4)带参数的装饰器 的相关文章

  • 解决cv_bridge依赖opencv版本问题

    1 问题来源 在安装ros的过程中 xff0c 系统会默认安装cv bridge库 xff0c 但该库指定了依赖的opencv库路径 xff0c 拿ros melodic版本来说 xff0c 默认依赖opencv库 usr lib x86
  • 使用ORB_SLAM3运行Realsense T265

    关于硬件 官网说明 使用说明 Realsense T265是一款跟踪相机 xff0c 配有两个FOV为111 7 x 108 6的广角相机 xff0c 并且带有IMU BMI055 惯性测量单元 设备内部配有vpu处理器并嵌入了建图和定位算
  • ceres-solver和g2o性能比较

    前言 ceres solver 和 g2o 是slam领域常见的优化器 xff0c 其中ceres solver被vins mono使用 xff0c 而g2o被orb slam3使用 xff0c 因此到底哪个优化器更适合于在slam算法开发
  • FreeRTOS的vTaskDelete使用说明

    FreeRTOS的vTaskDelete使用说明 函数说明 参数 xff1a xTaskToDelete 要删除的任务的任务句柄 返回值 无 说明 删除一个用函数xTaskCreate 或者xTaskCreateStatic 创建的任务 x
  • 机器学习——随机森林(Random Forest)

    1 随机森林 xff08 random forest xff09 简介 随机森林是一种集成算法 xff08 Ensemble Learning xff09 xff0c 它属于Bagging类型 xff0c 通过组合多个弱分类器 xff0c
  • 《基础知识——C和C++的主要区别》

    C和C 43 43 的主要区别 设计思想上 xff1a C 43 43 是面向对象的语言 xff0c 而C是面向过程的结构化编程语言 语法上 xff1a C 43 43 具有封装 继承和多态三种特性 C 43 43 相比C xff0c 增加
  • 数据库原理及应用(十三)E-R图、关系模式

    数据库设计的过程 数据分析 gt 数据建模 gt 关系数据库模式 gt 关系数据库管理 用户需求 gt 概念模型 E R Model gt 逻辑模型 xff08 三层结构 xff09 现实世界 gt 信息世界 gt 机器世界 概念设计工具E
  • Ubuntu数据备份与恢复工具(一)

    在我们日常工作中 xff0c 个人文件 业务数据及应用信息的备份与恢复策略是一个重要的环节 意外删除 硬件故障 操作失误 网络攻击 xff0c 甚至是自然灾害 xff0c 都可以直接或间接导不可估价的数据损失 为了避免损失 xff0c 缩少
  • 百度移动端面试回忆

    百度一面 xff1a 1 自我介绍 2 悲观锁和乐观锁 乐观锁 xff1a 总是认为不会产生并发问题 xff0c 每次去取数据的时候总认为不会有其他线程对数据进行修改 xff0c 因此不会上锁 xff0c 但是在更新时会判断其他线程在这之前
  • Quagga编译安装

    Quagga源码编译安装 1 Quagga下载 1 官网下载quagga 1 2 4 tar gz并拖入虚拟机桌面 2 解压到 opt目录下 sudo tar zxvf Desktop quagga 1 2 4 tar gz C opt 2
  • VINS-FUSION 源码 双目 单线程 按执行顺序阅读

    VINS FUSION 源码 双目 单线程 按执行顺序阅读 Keywords xff1a VINS FUSION vins 源码解读 源码梳理 vins数据结构 vinsfusion vins双目 双目vins 双目vinsfusion 双
  • 【C语言】__attribute__使用

    一 介绍 GNU C 的一大特色就是 attribute 机制attribute 可以设置函数属性 xff08 Function Attribute xff09 变量属性 xff08 Variable Attribute xff09 和类型
  • Ubuntu20.04下CUDA、cuDNN的详细安装与配置过程(图文)

    Ubuntu20 04下CUDA cuDNN的详细安装与配置过程 xff0c 亲测试可用 xff08 图文 xff09 一 NVIDIA xff08 英伟达 xff09 显卡驱动安装1 1 关闭系统自带驱动nouveau2 2 NVIDIA
  • 使用动量(Momentum)的SGD、使用Nesterov动量的SGD

    使用动量 Momentum 的SGD 使用Nesterov动量的SGD 参考 xff1a 使用动量 Momentum 的SGD 使用Nesterov动量的SGD 一 使用动量 Momentum 的随机梯度下降 虽然随机梯度下降是非常受欢迎的
  • Data Uncertainty Learning in Face Recognition

    Data Uncertainty Learning in Face Recognition 建模数据的不确定性对含噪音图像非常重要 xff0c 但对于人脸识别的研究却很少 先驱者的工作 35 通过将每个人脸图像嵌入建模为高斯分布来考虑不确定
  • ENAS代码解读

    ENAS代码解读 参考代码 xff1a https github com TDeVries enas pytorch 数据集 xff1a cifar10 main函数 xff1a span class token keyword def s
  • PC-DARTS Partial Channel Connections for Memory-Efficient Differentiable Architecture Search

    PC DARTS Partial Channel Connections for Memory Efficient Differentiable Architecture Search Abstract 可微体系结构搜索 xff08 DAR
  • deepsort代码解析

    DeepSort代码解析 项目地址 xff1a deepsort span class token keyword if span name span class token operator 61 61 span span class t
  • CBAM

    CBAM 我们提出了卷积块注意力模块 xff08 CBAM xff09 xff0c 这是一个简单而有效的前馈卷积神经网络的注意力模块 给定一个中间特征图 xff0c 我们的模块沿着通道和空间两个独立的维度依次推导注意力图 xff0c 然后将
  • onos2.0编译安装(npm install和 build问题解决)

    onos编译安装 Ubuntu16 04 1 前置下载安装 1 1 前置包安装 sudo apt get install git sudo apt get install python Oracle JDK8 sudo apt get in

随机推荐