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装饰器详解(四)---把参数传递给装饰器 的相关文章

随机推荐

  • 【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