❤️今天,该让 python 上个热门❤️

本文深入探讨Python装饰器的使用,包括普通装饰器、装饰带参数的函数、通用装饰器、装饰器装饰类以及装饰器传参数。通过案例展示了如何统计函数运行时间、处理带参数的函数以及创建类装饰器。此外,还讲解了如何定义可接受参数的装饰器,以及使用类作为装饰器的方法。总结了装饰器在不同场景下的应用和实现方式。

在这里插入图片描述

01.普通装饰器

详解 python 各种装饰器的实现,我们先来看一个普通的装饰器函数。

def decorator(fun):
    def func_w():
        print('---装饰器扩展的新功能')
        fun()
    return func_w

@decorator   :
def func_demo(a,b):
    res = a/b
    print('a除B的结果为:',res)
  
# @decorator这是样的写法是python中的一个语法糖,
#它的一个等同所有就是原来的这句 @decorator=====》func_demo= decorator(func_demo) 

装饰器原理阐述: 将被装饰的函数当做一个参数传到装饰器中,并且让被装饰的函数名指向装饰器内部的函数,在装饰器的内部函数中用接收到的参数再调用被装饰的函数。

案列、 使用装饰器来统计函数运行的时间

import time

def decorator(func):
    def fun():
        strat_time = time.time()  #获取开始时的时间
        func()  #运行被装饰的函数
        end_time = time.time()   # 获取结束时的时间
        t_time = end_time - strat_time  #算出运行总时间
        print('运行总时间%s'%t_time)  #打印运行总时间
    return fun

@decorator
def work():
    time.sleep(2)
    print('原来函数的功能代码')
      
work()

02.装饰带参数的函数

● 被装饰器的函数带参数怎么处理?

在内部的闭包函数中接收一个参数,然后在调用原功能函数时再把接收到的参数传入即可。

def decorator(func):
    def fun(a,b):
        print('-----装饰器实现的功能-------'))
        func(a,b)
    return fun

@decorator
def func(a,b):
    print("----执行函数--func-----")
    print(a+b)

03.通用装饰器

● 被装饰的函数,一部分带参数,一部分不带参数怎么处理?

○ 如果同一个装饰器既要装饰有参数的函数,又要装饰无参数的函数,那么我们在传参的时候就设置成不定长参数,这样不管被装饰的函数有没有参数都能用。

def decorator(func):
    def fun(*args,**kwargs):
        print('-----执行装饰器实现的功能-------')
        func(*args,**kwargs)
    return fun

@decorator
def func(a,b,f):
    print("----执行函数--func-----")
    print(a+b+f)

func(10,20,30)

04.装饰器装饰类

装饰器装饰类本质上和装饰函数没有区别,同样是把被装饰的类和函数当成参数传入装饰器中,把返回的结果传递给原来定义的类去接收。

就是说装饰完之后,原来定义的类名,指向的就是装饰器内部的嵌套函数了。

def decorator(func):
    def fun(*args,**kwargs):
        print('-----执行装饰器实现的功能-------')
        return  func(*args,**kwargs)
    return fun


@decorator  # @decorator  等同于 Hero = decorator(Hero) 
class Hero(object):
    def __init__(self,name,age):
        self.name=name
        self.age=age
        print('正在初始化')

    def move(self):
        print('%s在快速移动'%self.name)

laoli = Hero('老李',19)

使用类装饰器的时候,记得要返回被装饰的类调用的结果。

05.装饰器传参数

前面介绍的几种装饰器在使用的时候不需要传递参数,那么如果在装饰器的时候需要传参数该怎么去实现呢?


# 定义可以传参的装饰器
def musen(name, age):
    def decoreter(func):
        def wrapper(*args, **kwargs):
            print("装饰器传递的参数name:", name)
            print("装饰器传递的参数age:", age)
            func(*args, **kwargs)
        return wrapper
    return decoreter

# 使用装饰器并传参
@musen('木森',18)
def work():
    print('原功能函数的代码')
  
# 代码解析:上面装饰的哪一行代码,的效果等同于work = musen('木森',18)(work)
# 意思就是先调用musen('木森',18) 使用调用的结果去装饰work,然后再把结果赋值给work

总结:

● 最外层参数,接收的是装饰器的参数

● 第二层参数,接收是被装饰的函数

● 第三层参数,接收的是被装饰函数的参数

06.类实现装饰器

前面我们是用闭包函数来实现的装饰器,那么接下来给大家扩展一下,使用类来当做一个装饰器来用

● 如果要把类当做一个装饰器来用,有两步操作,

  • 首先在 init 方法中,把被装饰的函数赋值给一个实例属性,
  • 然后再了类里面实现一个 call 方法,在 call 方法中调用原来的函数。
class Test(object):
   
    def __init__(self,func):  
        self.func = func
      
    def __call__(self, *args, **kwargs):
        print('这个是类装饰器')
        self.func(*args,**kwargs)

# 说明:
# 1. 当用Test来装作装饰器对func函数进行装饰的时候,首先会创建Test的实例对象,并且会把func这个函数名当做参数传递到__init__方法中,即在__init__方法中的func变量指向了func函数体
# 2. func函数相当于指向了用Test创建出来的实例对象
# 3. 当在使用func()进行调用时,就相当于让这个对象(),因此会调用这个对象的__call__方法
# 4. 为了能够在__call__方法中调用原来func指向的函数体,所以在__init__方法中就需要一个实例属性来保存这个函数体的引用,所以才有了self.__func = func这句代码,从而在调用__call__方法中能够调用到func之前的函数体

在这里插入图片描述

最后: 可以关注公众号:伤心的辣条 ! 进去有许多资料共享!资料都是面试时面试官必问的知识点,也包括了很多测试行业常见知识,其中包括了有基础知识、Linux必备、Shell、互联网程序原理、Mysql数据库、抓包工具专题、接口测试工具、测试进阶-Python编程、Web自动化测试、APP自动化测试、接口自动化测试、测试高级持续集成、测试架构开发测试框架、性能测试、安全测试等。

如果我的博客对你有帮助、如果你喜欢我的博客内容,请 “点赞” “评论” “收藏” 一键三连哦!


好文推荐

转行面试,跳槽面试,软件测试人员都必须知道的这几种面试技巧!

面试经:一线城市搬砖!又面软件测试岗,5000就知足了…

面试官:工作三年,还来面初级测试?恐怕你的软件测试工程师的头衔要加双引号…

什么样的人适合从事软件测试工作?

那个准点下班的人,比我先升职了…

测试岗反复跳槽,跳着跳着就跳没了…

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值