• python进阶之装饰器之4在类中定义装饰器,将装饰器定义为类,两者的区别与联系


    4.1 在类中定义装饰器

          以实例或者以类方法的形式进行应用

    代码解析:

    from functools import wraps
    
    class A:
        # Decorator as an instance method
        def decorator1(self, func):
            @wraps(func)
            def wrapper(*args, **kwargs):
                print('Decorator 1')
                return func(*args, **kwargs)
            return wrapper
    
        # Decorator as a class method
        @classmethod
        def decorator2(cls, func):
            @wraps(func)
            def wrapper(*args, **kwargs):
                print('Decorator 2')
                return func(*args, **kwargs)
            return wrapper
        
        
    # As an instance method
    a = A()
    @a.decorator1
    def spam():
        pass
    
    
    # As a class method
    @A.decorator2
    def grok():
        pass
    
    
    
    # 这种方法在标准库中就有示例,比如说@property,实际是拥有
    # getter()/setter()/deleter()方法的类,类中每一个定义的方
    # 法可以作为装饰器
    # 比如代码如下:
    class Person:
        # Create a property instance
        first_name = property()
    
        # Apply decorator methods
        @first_name.getter
        def first_name(self):
            return self._first_name
    
        @first_name.setter
        def first_name(self, value):
            if not isinstance(value, str):
                raise TypeError('Expected a string')
            self._first_name = value

    4.2 把装饰器定义为类

    定义中需要实现__call__(),__get__() 方法
    # 把装饰器定义为类
    # 定义中需要实现__call__(),__get__() 方法
    
    
    import types
    from functools import wraps
    class Profiled:
        def __init__(self, func):
            wraps(func)(self)
            self.ncalls = 0
    
        def __call__(self, *args, **kwargs):
            self.ncalls += 1
            return self.__wrapped__(*args, **kwargs)
    
        def __get__(self, instance, cls):
            if instance is None:
                return self
            else:
                return types.MethodType(self, instance)
    
    # 在类外使用装饰器
    @Profiled
    def add(x, y):
        return x + y
    
    # 在类中使用装饰器
    class Spam:
        @Profiled
        def bar(self, x):
            print(self, x)
    
    
    print(add(2, 3))    #5
    print(add(3, 3))    #6
    print(add(4, 3))    #7
    print(add.ncalls)   #3
    
    
    
    s = Spam()
    print(s.bar(1))         #<__main__.Spam object at 0x000001F39D74D4E0> 1
    print(s.bar(2))         #<__main__.Spam object at 0x000001F39D74D4E0> 2
    print(s.bar(3))         #<__main__.Spam object at 0x000001F39D74D4E0> 3
    print(Spam.bar.ncalls)  #3
    print(s.bar.ncalls)     #3
    仙衣眠云碧岚袍,一襟潇洒,两袖飘飘。玉墨舒心春酝瓢,行也逍遥,坐也逍遥。
  • 相关阅读:
    如何在vim中同时编辑多个文件
    Windows操作系统架构
    驱动中PAGED_CODE的作用
    Process Hacker源码中的用户态hook的做法
    IO Processing
    Device Drivers
    Windows IO System
    how to catch error in make error message
    分析/proc/[pid]/maps中的各个内存区域的大小
    boost::shared_ptr
  • 原文地址:https://www.cnblogs.com/max520liuhu/p/9349360.html
Copyright © 2020-2023  润新知