python装饰器详解(四)---把参数传递给装饰器

2023-05-16

因为装饰器必须接收一个函数当做参数,所以不可以直接把被装饰函数的参数传递给装饰器.

装饰器就是一个普通的函数,回顾

def my_decorator(func):
   
print("I am an ordinary function")
   
def wrapper():
       
print("I am function returned by thedecorator")
       
func()
    return wrapper

因此,同样可以像普通函数一样调用装饰器,而不用@

def lazy_function():

    print("zzzzz")

调用,

decorated_function =my_decorator(lazy_function)  ##后面加()就会输出整个装饰完的结果

输出

I am an ordinaryfunction


执行下面的代码段:

@my_decorator
def lazy_function():

    print("zzzzz")


同样输出

I am an ordinaryfunction


    和"my_decorator"一样只是被调用.所以当你@my_decorator你只是告诉Python去掉用被变量my_decorator标记的函数.并没有调用要装饰的函数。

切记:标记能直接指向装饰器.

再看下面的例子:

def decorator_maker():
   
print("I make decorators! I am excuted only once:whenyou make me create a decorator.")

   
def my_decorator(func):
       
print("I am a decorator! I am executed only whenyou decorate a function.")
       
def wrapped():
           
print("I am the wrapper around the decoratedfunction.I am called when you callthe decorated function,As the wrapper, I return the result of the decoratedfunction!")
           
return func()
       
print("As the decorator,I return the wrappedfunction")
       
return wrapped
   
print("Asthe decorator maker , I return a decorator")
   
return my_decorator

建一个装饰器,它只是一个新函数

new_decorator =decorator_maker()   #返回一个装饰器函数

输出

#I make decorators! Iam executed only once: when you make me create a decorator.
#As a decorator maker, I return a decorator

下面来装饰一个函数

def decorated_function():
   
print("I am the decorated_function")

decoration_function =new_decorator(decorated_function)   #decorator_maker返回了装饰器函数,这里加上括号及参数相当于调用了装饰器函数,执行了my_decorator(func),并未装饰,返回装饰器,就像本文开始的调用一样。

输出

#I am a decorator! Iam executed only when you decorate a function.

#As the decorator, I return the wrapped function


下面执行装饰器函数

decoration_function() #上面的装饰器函数返回了装饰器,这里加上括号才执行了装饰器

输出

#I am the wrapperaround the decorated function. I am called when you call the decoratedfunction.
#As the wrapper, I return the RESULT of the decorated function.
#I am the decorated function.

注意上述红色字体的解释部分!!

去掉上述过程中的中间变量,

def decorated_function():
   
print("I am the decorated_function")


decorated_function = decorator_maker()(decorated_function)

此时输出

#I make decorators! I am executed onlyonce: when you make me create a decorator.

#As a decorator maker, I return a decorator

#I am a decorator! I am executed only whenyou decorate a function.

#As the decorator, I return the wrappedfunction.

最后再次调用得到的函数

decorated_function()

输出

#I am the wrapper around the decoratedfunction. I am called when you call the decorated function.

#As the wrapper, I return the RESULT of thedecorated function.

#I am the decorated function.


简化一下:

@decorator_maker()   ###加括号的
def decorated_function():

    print("Iam the decorated_function")


执行上述代码段,输出

#I make decorators! I am executed onlyonce: when you make me create a decorator.

#As a decorator maker, I return a decorator

#I am a decorator! I am executed only whenyou decorate a function.

#As the decorator, I return the wrappedfunction.


最终,执行

decorated_function()

输出

#I am the wrapper around the decoratedfunction. I am called when you call the decorated function.

#As the wrapper, I return the RESULT of thedecorated function.

#I am the decorated function.


所以装饰器的参数问题可以通过上述思路解决!

def decorator_maker_arguments(decorator_arg1,decorator_arg2):
 
  print("Imake decorators!And I accept argument:",decorator_arg1,decorator_arg2)
   
def my_decorator(func):
       
# 这里传递参数的能力是借鉴了 closures.
       
# 如果对closures感到困惑可以看看下面这个:
       
#http://stackoverflow.com/questions/13857/can-you-explain-closures-as-they-relate-to-python
       
print("Iam the decorator. somehow you pass me arguments:",decorator_arg1,decorator_arg2)

       
# 不要忘了装饰器参数和函数参数!
       
def wrapped(function_arg1,function_arg2):
           
print("Iam the wrapper around the decorated function.\nI can access all thevariables\n\t-fromthe decorator:{0}{1}\n\t-fromthe function call:{2}{3}\nThen I can pass them to the decorated function".format(decorator_arg1,decorator_arg2,function_arg1,function_arg2))
           
return func(function_arg1,function_arg2)
       
return wrapped
   
return my_decorator


@decorator_maker_arguments("Leonard","Sheldon")
defdecorated_function_with_arguments(function_arg1,function_arg2):
   
print("I am the decoratedfunction and only knows about my arguments: {0}{1}".format(function_arg1,function_arg2))


执行

decorated_function_with_arguments("Rajesh","Howard")


输出

#I make decorators! And I accept arguments:Leonard Sheldon

#I am the decorator. Somehow you passed mearguments: Leonard Sheldon

#I am the wrapper around the decoratedfunction.

#I can access all the variables

#   - from thedecorator: Leonard Sheldon

#   - from the functioncall: Rajesh Howard

#Then I can pass them tothe decorated function

#I am the decorated function and only knows about my arguments: Rajesh Howard


上面就是带参数的装饰器.参数可以设置成变量:


c1 = "Penny"
c2 = "Leslie"
@decorator_maker_arguments("Leonard",c1)
def decorated_function_with_arguments(function_arg1,function_arg2):
    print("I am the decorated function and only knows about my arguments: {0}{1}".format(function_arg1,function_arg2))

decorated_function_with_arguments(c2,"Howard")  

#输出:

#I make decorators! And I accept arguments:Leonard Penny

#I am the decorator. Somehow you passed mearguments: Leonard Penny

#I am the wrapper around the decoratedfunction.

#I can access all the variables

#   -from the decorator: Leonard Penny

#   -from the function call: Leslie Howard

#Then I can pass them to the decoratedfunction

#I am the decorated function and only knowsabout my arguments: Leslie Howard


    可以用这种方式把任何函数的参数传递给装饰器.还可以用*args,**kwargs.

    但是一定要记住了装饰器只能被调用一次.

    当Python载入脚本后,就不可以动态的设置参数了.当你运行import x,函数已经被装饰,所以你什么都不能动了.


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

python装饰器详解(四)---把参数传递给装饰器 的相关文章

  • 如何在anaconda python 3.6上安装tensorflow

    我使用 anaconda 包安装了新版本的 python 3 6 但是我无法安装张量流 总是收到这样的错误 tensorflow gpu 1 0 0rc2 cp35 cp35m win amd64 whl 在此平台上不受支持 如何在 ana
  • 让 Django 提供可下载文件

    我希望网站上的用户能够下载路径被遮挡的文件 因此无法直接下载它们 例如 我希望 URL 是这样的 http example com download f somefile txt 在服务器上 我知道所有可下载的文件都位于该文件夹中 home
  • 绘制对数轴

    我想使用 matplotlib 绘制一张带有一个对数轴的图 我一直在阅读文档 但无法弄清楚语法 我知道这可能很简单 scale linear 在情节争论中 但我似乎无法正确理解 示例程序 import pylab import matplo
  • PyQt5 的 OpenGL 模块和版本控制问题(调用不正确的 _QOpenGLFunctions_(ver))

    我一直在努力得到PyQt5 helloGL 示例代码 https github com baoboa pyqt5 blob master examples opengl hellogl py编译 当我尝试构建解决方案时 我得到 Traceb
  • Python 中 eval("input()") 和 eval(input()) 之间的区别

    我正在尝试以下功能 x eval input 输入为 123 x 的类型也是int 它工作正常 In 22 x eval input enter enter 123 In 24 print type x
  • NumPy 根据另一个数组中的值对第三个数组中的每个匹配元素求和一个数组

    我有两个 numpy 数组 一个包含值 另一个包含每个值类别 values np array 1 2 3 4 5 6 7 8 9 10 valcats np array 101 301 201 201 102 302 302 202 102
  • Python 中的 Firebase 身份验证时出现 KeyError:“databaseURL”

    相信你做得很好 我是 firebase 的新手 正在尝试进行用户身份验证 我已经安装了pyrebase4并在firebase控制台上创建了一个项目 我还启用了使用 电子邮件和密码 登录并尝试连接我的应用程序 下面是我正在尝试的代码 impo
  • Python:两个列表之间的成对比较:列表 a >= 列表 b?

    如果我想检查列表中的所有元素 a 1 2 3 6 大于或等于另一个列表中对应的元素 b 0 2 3 5 如果 a i gt b i 对于所有i的 则返回 true 否则返回 false 这有逻辑功能吗 比如a gt b 谢谢 你可以这样做
  • 在python中检测按下了哪些键

    我需要知道现在按下的是哪个键 我不想捕获一些特定的按键来触发事件或类似的事情 我想知道现在按下了哪些键并显示它们的列表 我还需要捕获特殊键 如 F1 F12 shift alt home windows 等 基本上是键盘上的所有键 我如何在
  • 如果任何单元测试失败,如何使 Python 的覆盖率工具失败?

    我想使用 shell 脚本来确保我的单元测试通过and我的代码有足够的测试覆盖率 我只想运行我的测试代码once 我希望我可以通过coverage https coverage readthedocs io 工具和单次运行的工具 如果一项或
  • 使用 Celery 通过 Gevent 进行实时、同步的外部 API 查询

    我正在开发一个 Web 应用程序 该应用程序将接收用户的请求 并且必须调用许多外部 API 来编写对该请求的答案 这可以直接从主 Web 线程使用 gevent 之类的东西来扇出请求来完成 或者 我在想 我可以将传入的请求放入队列中 并使用
  • Tensorflow `tf.layers.batch_normalization` 不会向 `tf.GraphKeys.UPDATE_OPS` 添加更新操作

    以下代码 复制 粘贴可运行 说明了如何使用tf layers batch normalization import tensorflow as tf bn tf layers batch normalization tf constant
  • 如何仅在按下某个键时触发鼠标单击?在Python中

    我想制作一个程序 或者当我单击某个键时 鼠标会自动单击 只要我单击该键 如果我不单击该键 它就会停止 我不希望只在触摸按键一次时才发生点击 而是只要按住按键就发生点击 也可以像雷蛇突触鼠标一样按下鼠标左键触发点击 任何想法 EDIT 1 这
  • 检查图像中是否有太薄的区域

    我正在尝试验证雕刻机的黑白图像 更多的是剪贴画图像 不是照片 我需要考虑的主要事情之一是区域的大小 或线条的宽度 因为机器无法处理太细的线条 所以我需要找到比给定阈值更细的区域 以此图为例 竖琴的琴弦可能太细而无法雕刻 我正在阅读有关 Ma
  • 使用 Python 获取 Youtube 数据

    我正在尝试学习如何分析网络上可用的社交媒体数据 我从 Youtube 开始 from apiclient errors import HttpError from outh2client tools import argparser fro
  • Hoare Partitioning算法讲解

    根据许多网站给出的伪代码 我写了这个Hoare分区算法 它采用一个数组 根据给定的主元来分区子数组的开始和结束索引 它工作得很好 但是有人可以解释一下逻辑 它是如何做到这一点的吗 这是代码 def hoare arr start end p
  • 内置模块位于哪里?

    我尝试查找列出的所有目录sys path但我找不到任何builtins py文件 那么它在哪里呢 从字面上看 该模块内置于 python 解释器中 gt gt gt import builtins gt gt gt builtins
  • `numpy.diff` 和 `scipy.fftpack.diff` 在微分时给出不同的结果

    我正在尝试计算一些数据的导数 并且正在尝试比较有限差分的输出和谱方法的输出 但结果却截然不同 我无法弄清楚到底为什么 考虑下面的示例代码 import numpy as np from scipy import fftpack as sp
  • 如何通过解析导入来组合并获取单个 Python 文件

    我正在尝试获取单个 Python 文件作为输出 我有一个 Python 脚本 其中有多个此类导入 from that import sub 导入来自所有本地模块 而不是来自系统或 Python 库 有什么方法可以解决这些问题并获得一个完整的
  • 如何使用多阶段构建减小 python (docker) 图像大小?

    我正在寻找一种使用 python 和 Dockerfile 创建多阶段构建的方法 例如 使用以下图像 第一张图片 安装所有编译时要求 并安装所有需要的 python 模块 第二张图片 将所有已编译 构建的包从第一个映像复制到第二个映像 而不

随机推荐

  • 【SDN控制器】odl:0.6.4集群搭建遇到的问题

    一 环境 ubuntu16 04虚拟机 xff0c 使用odl的docker镜像 xff0c 建立三个odl容器 xff0c 进行端口映射 odl 1 sudo docker run it name odl 1 p 10001 8181 P
  • 嵌入式开发仿真软件——proteus8.15

    File Name main c Description Main program body COPYRIGHT c 2017 STMicroelectronics Redistribution and use in source and
  • Windows将FRP设置为服务并开机自启

    1 此处需要使用到winsw 下载地址 https github com kohsuke winsw releases 2 下载解压至任意目录并CD进入 这里将下载WinSw Net4 exe重命名为winsw exe了 xff0c 以方便
  • 使用HAL库驱动WS2812 LED的STM32F401代码示例

    使用HAL库驱动WS2812 LED的STM32F401代码示例 include 34 stm32f4xx hal h 34 include lt stdlib h gt define LED COUNT 10 TIM HandleType
  • 开源项目-esp32—S3+lvgl智能手表

    23 5 4 QF ZERO V2 V1 0 2 智能手表终端 嘉立创EDA开源硬件平台 oshwhub com 致敬大神 硬件资源 xff1a 1 xff09 ESP32 S3 为核心主控 xff0c 负责复杂的运算与交互处理 xff0c
  • nRF52832芯片使用ADC的代码示例

    nRF52832芯片使用ADC的代码示例 define ADC REF VOLTAGE IN MILLIVOLTS 600 lt Reference voltage in millivolts used by ADC while doing
  • nRF52832的I2C例程代码

    nRF52832的I2C例程代码 include 34 nrf drv i2c h 34 include 34 app error h 34 define I2C SCL PIN 0 SCL引脚号 define I2C SDA PIN 1
  • HX711 24位A/D模块计算公式

    基本原理讲解 100kg 传感器 满量程输出电压 61 激励电压 灵敏度2 0mv v 例如 xff1a 供电电压是5v 乘以灵敏度2 0mv v 61 满量程10mv 相当于有100Kg 重力产生时候产生10mV 的电压 711模块对产生
  • stm32 keil实现串口printf输出中文字符

    添加如下代码 xff0c 可以GNUC的方式实现 span class hljs comment ifdef GNUC span With GCC RAISONANCE small printf option LD Linker gt Li
  • stm32 基于TIM1定时器的PWM输出

    void PWM TIM1 uint16 t arr uint16 t psc RCC APB2PeriphClockCmd RCC APB2Periph TIM1 ENABLE 定时器TIM1时钟使能 TIM DeInit TIM1 设置
  • stm32 can总线参考例程

    CAN初始化 tsjw 重新同步跳跃时间单元 范围 1 3 CAN SJW 1tq CAN SJW 2tq CAN SJW 3tq CAN SJW 4tq tbs2 时间段2的时间单元 范围 1 8 tbs1 时间段1的时间单元 范围 1
  • 物联网IOT-mqtt协议

    MQTT是一种客户机服务器发布 订阅消息传递传输协议 它重量轻 开放 简单 设计简单 易于实现 这些特性使其非常适合在许多情况下使用 xff0c 包括受限的环境 xff0c 如机器间通信 M2M 和物联网 IoT 环境 xff0c 在这些环
  • 联合索引的最左匹配原则的成因

    联合索引的最左匹配原则的成因 上面我们只看的是单一的索引 xff0c 接下来咱们来看看联合索引 xff0c 也就是回答第二个问题 联合索引的最左匹配原则的成因 什么是联合索引呢 xff0c 就是由多列组成的索引了 那亦要了解其成因 xff0
  • 腾讯云轻量服务器的Ubuntu如何使用root(根)用户登陆ssh/Shell/terminal/终端/WindTerm/FinalShell

    Ubuntu 系统的默认用户名是 ubuntu xff0c 并在安装过程中默认不设置 root 帐户和密码 您如有需要 xff0c 可在设置中开启允许 root 用户登录 具体操作步骤如下 xff1a 使用 ubuntu 帐户登录轻量应用服
  • Ubuntu安装sshd服务

    ubuntu安装ssh服务 一 安装shhd SSH分客户端openssh client和openssh server 如果你只是想登陆别的机器的SSH只需要安装openssh client xff08 ubuntu有默认安装 xff0c
  • Linux环境(六)--资源与限制

    资源与限制 运行在Linux系统上的程序是有资源限制的 这些也许是硬件引起的限制 例如内存 xff0c 也许由系统策略引起的限制 例如 xff0c 允许 的CPU时间 xff0c 或者是实现的限制 例如 xff0c 整数的尺寸或是文件名允许
  • 遇到了C/C++控制台程序无法输入中文的情况

    其实C C 43 43 控制台程序无法cin中文的情况并不是你使用了string xff0c string是能输入并保存中文的 xff1b 经过一番探究 xff0c 我发现主要的问题是文件的编码和控制台所处的代码页 xff08 控制台的编码
  • Jpg2Dcm中文乱码问题

    Jpg2Dcm中文乱码问题 最近老板提出了一个新的功能要求 xff0c 希望可以把图片转成dcm 在实现功能的问题中遇见了很多问题和掉过许多坑 于是在此记录下来 问题 xff1a 第一次在进行Jpg2Dcm时 xff0c 可以进行图片转dc
  • 神经网络的数学表达式,神经网络的数学理论

    什么是神经网络 神经网络可以指向两种 xff0c 一个是生物神经网络 xff0c 一个是人工神经网络 生物神经网络 xff1a 一般指生物的大脑神经元 xff0c 细胞 xff0c 触点等组成的网络 xff0c 用于产生生物的意识 xff0
  • python装饰器详解(四)---把参数传递给装饰器

    因为装饰器必须接收一个函数当做参数 所以 不可以直接把被装饰函数的参数传递给装饰器 装饰器就是一个普通的函数 xff0c 回顾 def my decorator func print 34 I am an ordinary function