Python 装饰器入门

引言

装饰器不仅是 Python 中最具魔力的语法之一,也是一种优雅处理函数逻辑增强的方式。本文将通过练手项目为例,带你吃透它的本质与用法。

什么是 Decorator(装饰器)?

装饰器本质上是一个“接收函数并返回新函数”的函数。

你可以把它想象成给函数加上“拦截器”,在不修改原函数代码的前提下,对其行为进行增强、包装、控制等操作。

实例入门:一个简单的装饰器

下面是一个最基础的装饰器

def my_decorator(func):
    def wrapper(*args, **kwargs):
        print("begin call")
        print("i guess params is", args, 'and', kwargs)
        print("i want to change it")

        # tuple 不可变,需要转为 list 再修改
        args = list(args)
        args[0] = "ALC"
        kwargs['what'] = 'a command'

        result = func(*args, **kwargs)

        print("after call")
        return result
    return wrapper

@my_decorator
def my_function(who: str, what: str):
    print(who, "Called", what)

调用这个方法:my_function("zunmx", what="a function")

输出结果:

begin call
i guess params is ('zunmx',) and {'what': 'a function'}
i want to change it
ALC Called a command
after call

我们可以看到,my_function 本身并没有改变,但它的行为被我们“劫持”并注入了新逻辑。这就是装饰器的核心威力。

带参数的装饰器

比如你想要一个函数执行多次怎么办?再写三行 for ?不优雅。用装饰器!

def repeat(times):
    def decorator(func):
        def wrapper(*args, **kwargs):
            for _ in range(times):
                func(*args, **kwargs)
        return wrapper
    return decorator

使用方式:

@repeat(3)
def hello_zunmx():
    print("hello zunmx")

执行hello_zunmx()

输出:

hello zunmx
hello zunmx
hello zunmx

非常自然,就像你定义了一个新语法一样。

多个装饰器叠加

@decorator1
@decorator2
def func():
    pass

等价于:

func = decorator1(decorator2(func))

这允许我们构建类似“中间件链”的结构,在 Web 框架中大量使用。
✅ 保留函数原信息(使用 functools.wraps)

装饰器默认会把原函数的名字、注释等覆盖掉,可以使用 @wraps(func) 保留:

from functools import wraps

def deco(f):
    @wraps(f)
    def wrapper(*args, **kwargs):
        return f(*args, **kwargs)
    return wrapper

装饰器可以做什么?

  1. 权限控制(权限注解)
  2. 缓存(如 @lru_cache)
  3. 异常捕获(如 retry 装饰器)
  4. 日志记录(自动打印调用信息)
  5. 计时器(性能分析)
  6. ......

结论

Python 装饰器初看可能有点“绕”,但当你掌握了其本质,可以少些很多代码,并且解耦,让方法更加“健壮”

评论 0

还没有评论,来说点什么吧。

提交后需要审核才会公开。