python装饰器

[复制链接]
发表于 2025-12-30 18:25:53 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

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

根本概念
高阶函数:继续一个或多个函数作为输入,大概输出一个函数的函数。
闭包:一个函数对象,记着了它被界说时的自由变量的值。‍

根本装饰器
界说装饰器
装饰器通常界说为一个外层函数,这个外层函数返回一个内层函数。内层函数负责实行现实的装饰逻辑。
  1. 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)。
调用过程:​​​​​​​
  1. say_hello 被传递给 my_decorator。my_decorator 返回 wrapper 函数。say_hello 现在指向 wrapper 函数。当调用 say_hello() 时,实际上是调用 wrapper()。
复制代码
带参数的装饰器
偶然候,我们盼望装饰器本身也能继续参数。这可以通过再嵌套一层函数来实现。​​​​​​​
  1. 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。​​​​​​​
  1. 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 还支持类装饰器。类装饰器通常用于修改类的活动。​​​​​​​
  1. 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!
复制代码
装饰器组合

可以将多个装饰器应用于同一个函数。装饰器的实行序次是从内到外。
  1. 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!
复制代码
带状态的装饰器
偶然候,我们盼望装饰器可以大概记着一些状态信息。这可以通过利用类来实现。
  1. 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
复制代码
现实应用
日志日志记载​​​​​​​
  1. 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)
复制代码
缓存​​​​​​​
  1. 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 中一个非常强大的工具,可以用来加强或修改函数和类的活动。通过明白和利用装饰器,你可以编写更加轻便、模块化和可维护的代码。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!qidao123.com:ToB企服之家,中国第一个企服评测及软件市场,开放入驻,技术点评得现金
回复

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表