类装饰器

作者: wit92 | 来源:发表于2020-06-15 00:11 被阅读0次
    1、 __call__

    __call__()的作用是使实例能够像函数一样被调用,同时不影响实例本身的生命周期

    class X(object):
        def __init__(self, a, b, range):
            self.a = a
            self.b = b
            self.range = range
        def __call__(self, a, b):
            self.a = a
            self.b = b
            print('__call__ with ({}, {})'.format(self.a, self.b))
        def __del__(self, a, b, range):
            del self.a
            del self.b
            del self.range
    
    >>> xInstance = X(1, 2, 3)
    >>> xInstance(1,2)
    __call__ with (1, 2)
    

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

    用类写装饰器,就要用到 __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__方法被执行

    相关文章

      网友评论

        本文标题:类装饰器

        本文链接:https://www.haomeiwen.com/subject/wwcxxktx.html