Python中的装饰器模式

Python中的装饰器模式

  • 什么是装饰器模式
  • Python中的装饰器
  • 装饰器的写法
  • 总结

什么是装饰器模式

官方的解释是:在不改变对象结构的情况下向现有对象添加功能,就增加功能来说,装饰器模式比生成子类更加灵活
翻译成通俗的语言就是:装饰器模式就是在现有的函数、类外面,套上一段逻辑,对其进行扩展。由于未改变其本身的结构,所以符合开闭原则。

Python中的装饰器

首先,Python中的一切都是对象,function、class也不例外,所以亦可以作为参数传递给其他函数(比如传递给装饰器)。因此,被装饰器修饰过的一切都是function,被装饰器修饰过的类会变成function!

def i_am_function(cls):
    def inner(*args, **kwargs):
        pass
    return inner


class IAmClass:
    pass


@i_am_function
class DecoratedClass:
    pass


if __name__ == "__main__":
    print(type(i_am_function))
    print(type(IAmClass))
    print(type(DecoratedClass))

Python中的装饰器模式_第1张图片
上面代码中的@i_am_function是个语法糖,本质上是把DecoratedClass作为参数传给了i_am_function,其实这样写也行DecoratedClass = i_am_function(DecoratedClass)
Python中的装饰器模式_第2张图片
Python中的装饰器模式_第3张图片

装饰器的写法

我们现在知道,装饰器其实就是给函数加个外套来扩展功能,所以装饰器应该怎么写呢?

def wrapper(func):
    def inner(*args, **kwargs):
        ret = func(*args, **kwargs)
        return ret
    return inner

其中,ret一般要与原函数返回同一类型对象,ret返回对象本身。
装饰器也可以接受一些其他参数,只要继续套娃就可以了

def wrapper(a, b):
    def inner2(func):
    	# 在调用之前做点啥,比如打印
    	print(a)
        def inner(*args, **kwargs):
            ret = func(*args, **kwargs)
            return ret 
        # 在调用之后做点啥,比如答应
        print(b)
     return inner2

如果用之前那段代码举例子的话,就是这样的:

def i_am_function(a, b):
    def canshu(func):
        def inner(*args, **kwargs):
            print(a, b)
        return inner
    return canshu


class IAmClass:
    pass


@i_am_function("bbb", "aaa")
class DecoratedClass:
    pass


if __name__ == "__main__":
    print(type(i_am_function))
    print(type(IAmClass))
    print(type(DecoratedClass))
    DecoratedClass()

Python中的装饰器模式_第4张图片

总结

装饰器在Python中是一个很常见的东西,弄懂它很重要。在实际编程中,想要不破坏原本的代码,就给函数添加新的功能,装饰器模式是一个很好的选择

你可能感兴趣的:(Python中的装饰器模式)