python——装饰器深入研究(三)

在人生的道路上,不管是潇洒走一回,或者是千山独行,皆须是自己想走的路,虽然,有的人并不是很快就能找到自己的方向和道路,不过,只要坚持到底,我相信,就一定可以找到自己的路,只要找到路,就不必怕路途遥远了。

导读:本篇文章讲解 python——装饰器深入研究(三),希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com,来源:原文

在这里插入图片描述


一、不带参数的装饰器

1、案例1

class Demo:
    pass

@Demo
def work():
    print('work开始工作')

if __name__ == '__main__':
    work()

def work():
TypeError: Demo() takes no arguments

第4、5行的代码的执行逻辑是:work=Demo(work)
相当于初始化一个实例对象,需要定义参数去接收work,案例2

2、案例2

class Demo:
    def __init__(self,func):
        self.func=func

@Demo
def work():
    print('work开始工作')

if __name__ == '__main__':
    work()

work()
TypeError: ‘Demo’ object is not callable

实例化对象,不能调用,如果想要调用需要使用__call__()方法

3、案例3

class Demo:
    def __init__(self,func):
        self.func=func

    def __call__(self, *args, **kwargs):
        self.func()

@Demo
def work():
    print('work开始工作')

if __name__ == '__main__':
    work()

work开始工作

二、带参数的装饰器

方法1:采用闭包

class Demo:

    def __init__(self,number):
        self.number=number

    def __call__(self,func, *args, **kwargs):

        def wrapper(*args,**kwargs):
            print('拓展功能1')
            res=func(*args,**kwargs)
            print('拓展功能2')
            return res
        return wrapper

@Demo(number=24)
def work(a,b):
    return a+b

if __name__ == '__main__':
    print(work(1,2))

拓展功能1
拓展功能2
3

方法二:不采用闭包

class Demo:
    def __init__(self,number):
        self.number=number

    def __call__(self, func):
        self.func=func
        return self.run

    def run(self,*args,**kwargs):
        print('拓展功能1')
        res=self.func(*args,**kwargs)
        print('拓展功能2')
        return res


@Demo(number=12)            #work=Demo(number=12)(work(a,b))
def work(a,b):
    return a+b
if __name__ == '__main__':
    print(work(11,22))

拓展功能1
拓展功能2
33

三、将多个装饰器封装到一个类里面

在这里插入图片描述

1、使用静态方法实现

class Mytest:

    @staticmethod
    def test1(func):

        def wrapper(*args,**kwargs):
            print('拓展功能1')
            res=func(*args,**kwargs)
            print('拓展功能2')
            return res
        return wrapper

    @staticmethod
    def test2(func):

        def wrapper(*args,**kwargs):
            print('拓展功能1')
            res=func(*args,**kwargs)
            print('拓展功能2')
            return res
        return wrapper

@Mytest.test1
def work1(a,b):
    return a+b

@Mytest.test2
def work2(a,b):
    return a-b


if __name__ == '__main__':
    print(work1(24,8))
    print(work2(24,8))

拓展功能1
拓展功能2
32
拓展功能1
拓展功能2
16

2、使用类方法实现

class Mytest:

    @classmethod
    def test1(cls,func):

        def wrapper(*args,**kwargs):
            print('拓展功能1')
            res=func(*args,**kwargs)
            print('拓展功能2')
            return res
        return wrapper

    @classmethod
    def test2(cls,func):

        def wrapper(*args,**kwargs):
            print('拓展功能1')
            res=func(*args,**kwargs)
            print('拓展功能2')
            return res
        return wrapper

@Mytest.test1
def work1(a,b):
    return a+b

@Mytest.test2
def work2(a,b):
    return a-b


if __name__ == '__main__':
    print(work1(24,8))
    print(work2(24,8))

四、多个装饰器同时装饰一个函数的执行顺序

test_datas = [{"title": "测试用例", "data": "data1", "res": 1}]

@ddt
class TestDemo:

    @unpack							test_demo=unpack(data(*test_datas)(test_demo))
    @data(*test_datas)				test_demo=data(*test_datas)(test_demo)
    def test_demo(self, item):
        print('执行测试用例')

执行顺序:

test_demo=unpack(data(*test_datas)(test_demo))


在这里插入图片描述

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/123202.html

(0)
飞熊的头像飞熊bm

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!