装饰器

类装饰器

  • 装饰器还有一种特殊的语法就是类装饰器,就是通过定义一个类来装饰函数
  • 注意
  1. 需要让类的实例对象能够像函数一样进行调用,需要在类里面使用__call__魔法方法,把类的实例变成可调用对象(callable 请求即付的);
  2. 类装饰器装饰函数功能在__call__方法里进行添加
class 类装饰器名(object):
    """类装饰器  都是装饰器的功能"""
    
    def __init__(self, 引用):
        """类似于 闭包装饰器中 外部函数 专门用来接受 原函数的引用"""
        self.func = 原函数引用
    
    def __call__(self, *args, **kwargs):
        """类似于 内部函数"""
        # 扩展功能
        ret = self.func(*args, **kwargs)  # 执行原函数功能
        # 扩展功能

@类装饰器名
def f1(arg):
    pass
    return xxx
    
# 灵魂语法: f1=类名(f1) f1从函数变成了对象, f1(xxx)实则是 f1.__call__(xxx)
resurlt = f1(yy)
  • 代码说明:
  1. @类装饰器名:等价于“函数引用 = 类名(函数引用)”,所以需要提供一个__init__方法,并多增加一个fn参数。
  2. __call__方法里进行对fn函数的装饰,可以添加额外的功能。

多个装饰器的使用

  • 直接上代码,根据代码理解
def make_div(func):
    """对被装饰的函数的返回值 div标签"""
    def inner(*args, **kwargs):
        return "<div>" + func(*args, **kwargs) + "</div>"
    return inner

def make_p(func):
    """对被装饰的函数的返回值 p标签"""
    def inner(*args, **kwargs):
        return "<p>" + func(*args, **kwargs) + "</p>"
    return inner

# 灵魂代码---------------------------------
# 装饰过程: 1、content = make_p(content) 
#          2、content = make_div(content)
# 合并:content = make_div(make_p(content))
@make_div
@make_p
def content():
    return "人生苦短"
result = content()
print(result)

--------------------------
<div><p>人生苦短</p></div>
  • 多个装饰器的装饰过程就是:离函数最近的装饰器先装饰,然后外面的装饰器再进行装饰由内到外的装饰过程