自学内容网 自学内容网

python装饰器

装饰器是 Python 中一个非常强大和灵活的特性,用于修改或扩展函数或方法的行为。装饰器本质上是一个高阶函数,它可以接受一个函数作为参数,并返回一个新的函数。装饰器通常用于日志记录、性能测试、事务处理、缓存、权限校验等场景。

基本概念

高阶函数:接受一个或多个函数作为输入,或者输出一个函数的函数。

闭包:一个函数对象,记住了它被定义时的自由变量的值。‍

基本装饰器

定义装饰器

装饰器通常定义为一个外层函数,这个外层函数返回一个内层函数。内层函数负责执行实际的装饰逻辑。

def my_decorator(func):    def wrapper():        print("Something is happening before the function is called.")        func()        print("Something is happening after the function is called.")    return wrapper@my_decoratordef say_hello():    print("Hello!")say_hello()

装饰器的工作原理

@符号:@decorator 是装饰器的语法糖,等价于 say_hello = my_decorator(say_hello)。

调用过程:​​​​​​​

say_hello 被传递给 my_decorator。my_decorator 返回 wrapper 函数。say_hello 现在指向 wrapper 函数。当调用 say_hello() 时,实际上是调用 wrapper()。

带参数的装饰器

有时候,我们希望装饰器本身也能接受参数。这可以通过再嵌套一层函数来实现。​​​​​​​

def repeat(num_times):    def decorator(func):        def wrapper(*args, **kwargs):            for _ in range(num_times):                result = func(*args, **kwargs)            return result        return wrapper    return decorator@repeat(3)def greet(name):    print(f"Hello, {name}!")greet("Alice")

保留元数据

使用装饰器后,原始函数的元数据(如名称、文档字符串等)会被覆盖。为了保留这些元数据,可以使用 functools.wraps。​​​​​​​

import functoolsdef my_decorator(func):    @functools.wraps(func)    def wrapper(*args, **kwargs):        print("Something is happening before the function is called.")        result = func(*args, **kwargs)        print("Something is happening after the function is called.")        return result    return wrapper@my_decoratordef say_hello():    """Say hello to the user."""    print("Hello!")print(say_hello.__name__)  # 输出: say_helloprint(say_hello.__doc__)   # 输出: Say hello to the user.

类装饰器

除了函数装饰器,Python 还支持类装饰器。类装饰器通常用于修改类的行为。​​​​​​​

def add_class_method(cls):    def decorator(func):        setattr(cls, func.__name__, func)        return cls    return decorator@add_class_methodclass MyClass:    passdef say_hello(self):    print("Hello from MyClass!")instance = MyClass()instance.say_hello()  # 输出: Hello from MyClass!

装饰器组合

可以将多个装饰器应用于同一个函数。装饰器的执行顺序是从内到外。

def decorator1(func):    def wrapper():        print("Decorator 1")        func()    return wrapperdef decorator2(func):    def wrapper():        print("Decorator 2")        func()    return wrapper@decorator1@decorator2def say_hello():    print("Hello!")say_hello()# 输出:# Decorator 1# Decorator 2# Hello!

带状态的装饰器

有时候,我们希望装饰器能够记住一些状态信息。这可以通过使用类来实现。

class Counter:    def __init__(self, func):        self.func = func        self.count = 0    def __call__(self, *args, **kwargs):        self.count += 1        print(f"Function {self.func.__name__} has been called {self.count} times")        return self.func(*args, **kwargs)@Counterdef say_hello():    print("Hello!")say_hello()  # 输出: Function say_hello has been called 1 timessay_hello()  # 输出: Function say_hello has been called 2 times

实际应用

日志记录​​​​​​​

import loggingdef log_function_call(func):    def wrapper(*args, **kwargs):        logging.info(f"Calling {func.__name__} with args={args} kwargs={kwargs}")        result = func(*args, **kwargs)        logging.info(f"{func.__name__} returned {result}")        return result    return wrapper@log_function_calldef add(a, b):    return a + badd(3, 5)

缓存​​​​​​​

from functools import lru_cache@lru_cache(maxsize=128)def fibonacci(n):    if n <= 1:        return n    return fibonacci(n - 1) + fibonacci(n - 2)print(fibonacci(10))  # 输出: 55

总结

装饰器是 Python 中一个非常强大的工具,可以用来增强或修改函数和类的行为。通过理解和使用装饰器,你可以编写更加简洁、模块化和可维护的代码。


原文地址:https://blog.csdn.net/m0_62283350/article/details/143489995

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!