python装饰器

Python装饰器(Decorator)详解

装饰器是Python中一个非常强大且灵活的功能,广泛应用于日志记录、权限校验、性能测试、缓存等场景。理解装饰器的原理和用法,能让你的代码更加优雅和高效。


目录

  • 什么是装饰器?
  • 装饰器的基本原理
  • 如何定义和使用装饰器
  • 带参数的装饰器
  • 多层装饰器
  • 使用functools.wraps保持函数元信息
  • 装饰器的应用场景
  • 小结

什么是装饰器?

装饰器本质上是一个函数,它接受一个函数作为参数,并返回一个新的函数,从而在不修改原函数代码的情况下,增强或改变函数的行为。

简单来说,装饰器就是“包装”函数的工具。


装饰器的基本原理

假设有一个函数func,我们想在调用它之前和之后打印日志:

def func():
    print("函数执行中")

def wrapper():
    print("开始执行")
    func()
    print("执行结束")

wrapper()

这段代码实现了功能,但如果想用装饰器写法:

def decorator(func):
    def wrapper():
        print("开始执行")
        func()
        print("执行结束")
    return wrapper

@decorator
def func():
    print("函数执行中")

func()

@decorator语法等价于func = decorator(func),调用func()时实际上调用的是wrapper()


如何定义和使用装饰器

简单装饰器示例

def decorator(func):
    def wrapper():
        print("调用前")
        func()
        print("调用后")
    return wrapper

@decorator
def say_hello():
    print("Hello!")

say_hello()

输出:

调用前
Hello!
调用后

带参数的装饰器

如果被装饰的函数有参数,装饰器内部的wrapper也需要接收参数:

def decorator(func):
    def wrapper(*args, **kwargs):
        print("调用前")
        result = func(*args, **kwargs)
        print("调用后")
        return result
    return wrapper

@decorator
def greet(name):
    print(f"Hello, {name}!")

greet("Alice")

多层装饰器

一个函数可以被多个装饰器装饰,装饰器会从内到外依次调用:

def deco1(func):
    def wrapper():
        print("deco1 start")
        func()
        print("deco1 end")
    return wrapper

def deco2(func):
    def wrapper():
        print("deco2 start")
        func()
        print("deco2 end")
    return wrapper

@deco1
@deco2
def say():
    print("Say something")

say()

输出:

deco1 start
deco2 start
Say something
deco2 end
deco1 end

使用functools.wraps保持函数元信息

装饰器会覆盖原函数的__name____doc__等属性,使用functools.wraps可以保持原函数信息:

import functools

def decorator(func):
    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        print("调用前")
        return func(*args, **kwargs)
    return wrapper

@decorator
def greet():
    """打招呼函数"""
    print("Hello!")

print(greet.__name__)  # greet
print(greet.__doc__)   # 打招呼函数

装饰器的应用场景

  • 日志记录:自动打印函数调用日志
  • 权限校验:检查用户权限,控制访问
  • 性能测试:统计函数执行时间
  • 缓存:缓存函数结果,避免重复计算
  • 输入校验:验证函数参数合法性

小结

  • 装饰器是接受函数并返回新函数的高阶函数。
  • 使用@decorator语法糖简化装饰器应用。
  • 支持带参数函数和多层装饰器。
  • 使用functools.wraps保持函数元信息。
  • 装饰器广泛应用于代码增强和功能复用。
posted @ 2025-07-08 10:11  爆爆啥龙马  阅读(48)  评论(0)    收藏  举报