c语言编程笔录

首页 >   > 笔记大全

笔记大全

读懂 Python 装饰器

更新时间:2023-11-30

什么是装饰器?

装饰器是Python中一种很重要且强大的语言结构,它可以动态的改变一个函数、方法或类的行为,而不需要修改它们的源代码。

一般来讲,装饰器是一个函数或类,它接收一个对象并返回另一个对象,同时该对象具备被装饰对象的所有特性,或者添加新的功能。装饰器实际上是调用函数或类,使用这种方式能够避免改变原始函数或类的基本行为,而是在不改变源码的情况下对其进行改进。因此,装饰器被广泛应用于实现横向逻辑切面。

def deco(f):
    def wrap():
        print('start...')
        f()
        print('end...')
    return wrap

@deco
def foo():
    print('test')

foo()

上面的代码中,我们定义了一个装饰器 @deco。该装饰器定义了一个内部函数 wrap,它输出一个开始信息并且调用原始函数 foo,最后输出结束信息。在定义完装饰器后,我们使用@deco装饰器来装饰原始函数 foo,这意味着将 foo 作为 deco 函数的参数并将结果重新赋值给 foo。最后调用 foo 函数时,实际上执行的是 wrap 函数。

装饰器的分类

根据装饰器的特性和应用场景,可以将装饰器分为几类。

修饰符装饰器

修饰符装饰器是一种特殊的装饰器,它们被用来修改函数的行为或实现特殊的功能。这种装饰器不需要在函数或方法前使用 @ 符号。

def with_logging(func):
    def wrapper():
        print("级别: 日志")
        return func()
    return wrapper

def prinlog():
    print('开始...')

with_logging(prinlog)()

这个例子使用了一个修饰符装饰器,即 with_logging 函数。该函数以一个函数作为参数,并返回一个修饰后的函数 wrapper。实际上,该函数调用原始 prinlog 函数,其前加了一行文本,指示该代码模块的当前日志级别,并且返回修改后的结果。

类装饰器

除了函数,在Python中还可以使用类作为装饰器。使用类装饰器可以在不使用函数闭包的情况下实现装饰器的功能。

class myDecorator(object):
    def __init__(self, f):
        self.f = f

    def __call__(self, *argc):
        print("Call entry...")
        self.f(*argc)
        print("Call exit.")

@myDecorator
def test(foo):
    print(foo)

test("Hello World!")

上面的示例使用了一个类装饰器。类装饰器包含了两个方法,其中 init 函数定义了一个默认的构造函数,它以 func 作为参数,并将其保存为 self.f 变量。call 函数是每次调用实例时调用的函数,它将在实例调用时修改函数的输出行为。

参数化装饰器

参数化装饰器是指装饰器函数本身具有参数的功能。这种装饰器类型的作用与普通装饰器类似,不过增加了一些参数的控制环节。

def logger(level):
    def decor(func):
        def wrapper(*args, **kwargs):
            print("log Level: ", level)
            func(*args, **kwargs)
        return wrapper
    return decor

@logger(level="DEBUG")
def say(something):
    print("say {}!".format(something))

say("Hello World!")

在这个示例中,我们定义了一个带有参数的装饰器 logger,该装饰器接收一个字符串参数 level。logger是一个高阶函数,它的代码逻辑如下:

  • 接收 level 参数
  • 定义一个 decor 函数,它接收一个 func 参数作为原函数,同时它也是一个高阶函数。
  • 定义一个 wrapper 函数,对 func 函数进行了日志记录。
  • 返回 wrapper 函数

调用函数时,使用 @logger(level="DEBUG") 的方式将装饰器和函数联系在一起。这将使我们的 say 函数刚调用时输出一个 DEBUG 级别的日志信息。

总结

Python装饰器是Python编程语言的一个强大特性,它可以动态地修改函数、方法或类的行为,而不需要修改这些对象的源代码。Python装饰器提供了一种方便的方法来实现横向逻辑切面。装饰器可以分为修饰符装饰器、类装饰器和参数化装饰器等。通过装饰器,我们可以在不改变原有设计实现的情况下,对其进行扩展、修改和优化。