boxmoe_header_banner_img

Hello! 欢迎来到悠悠畅享网!

文章导读

Python里@decorator用法 装饰器语法在Python中的实际应用解析


avatar
悠悠站长 2025年6月9日 2

装饰器是python中用于扩展函数或类功能的语法糖,本质是接收函数或类并返回新函数或类的可调用对象。1. 装饰器通过@符号应用,如@my_decorator装饰函数等价于将函数传递给装饰器函数并替换原函数;2. 常见用途包括记录日志/执行时间、权限控制、多层装饰器叠加使用,例如log_time装饰器可统一为函数添加耗时统计;3. 多个装饰器按从下往上的顺序依次执行,最靠近函数的装饰器最先被调用;4. 类也可作为装饰器,需实现__call__方法,适合需要维护状态的场景,如缓存结果或计数器。

在Python中,@decorator 是一种非常实用的语法糖,用来简化函数或类的装饰过程。简单来说,它允许你在不修改原函数代码的前提下,为其添加额外功能。这在实际开发中特别有用,比如权限校验、日志记录、性能统计等场景。


什么是装饰器(Decorator)

装饰器本质上是一个函数,也可以是类,它的作用是在不改变原函数调用方式的情况下,对函数的功能进行扩展。Python 中使用 @ 符号来应用装饰器,放在函数定义的上方。

例如:

@my_decorator def say_hello():     print("Hello")

上面这段代码等价于:

立即学习Python免费学习笔记(深入)”;

def say_hello():     print("Hello")  say_hello = my_decorator(say_hello)

也就是说,装饰器就是把一个函数传给另一个函数,并返回一个新的函数替代原来的函数。


装饰器的常见用途

1. 记录日志 / 函数执行时间

这是装饰器最典型的应用之一。你可以为多个函数统一加上日志输出或者计时功能,而无需重复写代码。

import time  def log_time(func):     def wrapper(*args, **kwargs):         start = time.time()         result = func(*args, **kwargs)         print(f"Call {func.__name__}, cost {time.time() - start:.4f}s")         return result     return wrapper  @log_time def do_something():     time.sleep(0.5)  do_something() # 输出类似:Call do_something, cost 0.5001s

注意:这里用了 *args 和 **kwargs 来兼容各种参数形式的函数,保证装饰器的通用性。


2. 权限控制与条件判断

你可以在执行某个函数前做一些检查,比如用户是否登录、输入是否合法等。

def login_required(func):     def wrapper(user, *args, **kwargs):         if user.is_authenticated:             return func(user, *args, **kwargs)         else:             print("请先登录")     return wrapper  class User:     def __init__(self, is_authenticated):         self.is_authenticated = is_authenticated  @login_required def access_data(user):     print("访问数据成功")  user = User(is_authenticated=False) access_data(user)  # 输出:请先登录

这样的结构可以让你集中处理权限逻辑,避免在每个业务函数里都加判断语句。


3. 多层装饰器叠加使用

你还可以在一个函数上叠加多个装饰器,它们会按顺序从下往上依次执行。

def decorator1(func):     def wrapper(*args, **kwargs):         print("Start decorator1")         result = func(*args, **kwargs)         print("End decorator1")         return result     return wrapper  def decorator2(func):     def wrapper(*args, **kwargs):         print("Start decorator2")         result = func(*args, **kwargs)         print("End decorator2")         return result     return wrapper  @decorator1 @decorator2 def test():     print("Test function")  test()  # 输出: # Start decorator1 # Start decorator2 # Test function # End decorator2 # End decorator1

小技巧:多个装饰器的执行顺序是从内到外,也就是最靠近函数的那个最先被调用。


使用类作为装饰器

除了函数,类也可以作为装饰器,只需要实现 __call__ 方法即可。

class MyDecorator:     def __init__(self, func):         self.func = func      def __call__(self, *args, **kwargs):         print("Before function call")         result = self.func(*args, **kwargs)         print("After function call")         return result  @MyDecorator def say_hi():     print("Hi")  say_hi()  # 输出: # Before function call # Hi # After function call

这种方式适合需要维护状态的情况,比如缓存中间结果、计数器等。


基本上就这些了。装饰器看起来有点“魔法”,但只要理解它是如何包装和替换函数的,其实并不难掌握。关键是要多练习几种不同类型的用法,比如带参数的装饰器、类方法装饰器等,才能在实际项目中灵活运用。



评论(已关闭)

评论已关闭