基于类的装饰器

1. __call__

前面介绍的装饰器都是用函数写的,其实,装饰器也可以用类来定义编写

用类写装饰器,就要用到 __call__ 方法,这个方法,允许你像调用函数一样去调用对象,下面是一个简单的示例来展示这种用法

class TestCall(object):
    def __call__(self, *args, **kwargs):
        print("执行了call方法")

tc = TestCall()
tc()
print(callable(tc))

程序执行结果为

执行了call方法
True

tc是一个对象,如果没有实现__call__方法,那么tc()这种写法是有问题的,但是由于实现了__call__方法,tc就是一个callable的对象了

这种技术在python的web框架里非常常见,__call__ 赋予了类对象和函数一样的被调用的能力,直白点说,函数和对象可以实现混用,因为他们都能被采用小括号的方式去调用

2. 类装饰器

下面是一个类装饰器的简单例子

import time


class Decorator(object):
    def __init__(self, func):
        self.func = func

    def __call__(self, *args, **kwargs):
        t1 = time.time()
        res = self.func(*args, **kwargs)
        t2 = time.time()
        print("函数执行时长:"+ str(t2 - t1))


@Decorator
def test():
    time.sleep(1.5)

test()

为了便于理解,下面的代码不采用@ 这种方式来进行装饰

f = Decorator(test)
f()

test函数作为参数初始化Decorator对象,此时,f.func = test, f是一个对象,但是由于实现了__call__方法,因此,可以直接像调用函数那样去调用对象, f(),此时,__call__方法被执行

扫描关注, 与我技术互动

QQ交流群: 211426309

加入知识星球, 每天收获更多精彩内容

分享日常研究的python技术和遇到的问题及解决方案