一、什么是装饰器?

在Python中,装饰器是一种特殊类型的函数,它可以接收一个函数作为参数,然后返回一个新的函数,以实现对原函数的修改或增强。这使得我们可以在不改变原函数代码的情况下,增加或修改函数的功能。
装饰器的语法形式是使用@符号,紧跟着装饰器函数的名字,然后在下一行定义需要被装饰的函数。例如:

def my_decorator(func):
    def wrapper():
        print("Before function call")
        func()
        print("After function call")
    return wrapper

@my_decorator
def say_hello():
    print("Hello, world!")

say_hello()

输出:

Before function call
Hello, world!
After function call

二、装饰器的使用场景

装饰器在许多场景中都非常有用,比如日志记录、性能测试、事务处理、缓存、权限校验等等。下面我们以日志记录为例,展示如何使用装饰器:

import logging

def log_decorator(func):
    def wrapper(*args, **kwargs):
        logging.info(f"Running {func.__name__}")
        return func(*args, **kwargs)
    return wrapper

@log_decorator
def add(x, y):
    return x + y

print(add(1, 2))

在这个例子中,我们定义了一个装饰器log_decorator,它会在函数调用前打印一条日志。然后我们将这个装饰器应用到函数add上。现在,每次我们调用add函数时,都会先打印一条日志。

三、多个装饰器的使用

一个函数可以被多个装饰器装饰,这时装饰器的应用顺序是从下到上,即离函数最近的装饰器会被首先应用。例如:

def decorator1(func):
    def wrapper():
        print("Decorator 1")
        func()
    return wrapper

def decorator2(func):
    def wrapper():
        print("Decorator 2")
        func()
    return wrapper

@decorator1
@decorator2
def say_hello():
    print("Hello, world!")

say_hello()

输出:

Decorator 1
Decorator 2
Hello, world!

四、带参数的装饰器

装饰器也可以接收参数,这时我们需要定义一个返回装饰器的函数。例如,我们可以定义一个带有日志级别参数的日志装饰器:

import logging

def log_decorator(level):
    def decorator(func):
        def wrapper(*args, **kwargs):
            if level == "info":
                logging.info(f"Running {func.__name__}")
            elif level == "debug":
                logging.debug(f"Running {func.__name__}")
            return func(*args, **kwargs)
        return wrapper
    return decorator

@log_decorator("info")
def add(x, y):
    return x + y

print(add(1, 2))

在这个例子中,我们定义了一个返回装饰器的函数log_decorator,它接收一个参数level,然后根据这个参数决定日志的级别。

五、类装饰器

除了函数装饰器外,Python还支持类装饰器。类装饰器实际上是一个类,它定义了一个__call__方法,使得它可以像函数一样被调用。类装饰器的主要优点是它可以保存状态信息。例如:

class CountCalls:
    def __init__(self, func):
        self.func = func
        self.num_calls = 0

    def __call__(self, *args, **kwargs):
        self.num_calls += 1
        print(f"Call {self.num_calls} of {self.func.__name__}")
        return self.func(*args, **kwargs)

@CountCalls
def say_hello():
    print("Hello, world!")

say_hello()
say_hello()

输出

Call 1 of say_hello
Hello, world!
Call 2 of say_hello
Hello, world!

六、结论

Python装饰器是一种强大的工具,它可以让我们更优雅、更便捷地修改或增强函数和方法的行为。以上就是对Python装饰器的基本介绍,希望对你有所帮助。

七、最后

如果觉得本文对你有帮助记得 **点个关注,给个赞,加个收藏,**更多精彩内容欢迎查看。

05-31 14:52