Python装饰器超详细实例教程

 更新时间:2026年05月14日 10:35:20   作者:星哲最开心  
本文介绍了Python装饰器的基本概念、用途和实现方法,装饰器是一种在不修改原函数代码的前提下,为函数动态添加功能的工具,其本质是闭包和高阶函数,装饰器可用于日志记录、计时、权限校验等功能,感兴趣的朋友跟随小编一起看看吧

Python 装饰器是在不修改原函数代码的前提下,给函数动态添加功能的工具,本质是闭包 + 高阶函数,最常用场景:日志记录、计时、权限校验、缓存、事务管理等。

先搞懂 3 个基础概念

装饰器建立在这三个知识点之上,必须先理解:

  1. 函数是一等公民:函数可以作为参数、返回值、赋值给变量
  2. 高阶函数:接收函数作为参数,或返回一个函数
  3. 闭包:内部函数可以访问外部函数的变量,且外部函数执行完毕后变量不销毁

最简单的装饰器(无参函数)

手动实现装饰器(理解原理)

# 定义装饰器:接收一个函数,返回一个新函数
def my_decorator(func):
    def wrapper():
        print("函数执行前:添加额外功能")
        func()  # 调用原函数
        print("函数执行后:添加额外功能")
    return wrapper
# 原函数
def say_hello():
    print("Hello 装饰器!")
# 手动装饰:不修改原函数,给它加功能
say_hello = my_decorator(say_hello)
# 调用
say_hello()

输出

函数执行前:添加额外功能
Hello 装饰器!
函数执行后:添加额外功能

语法糖 @(最常用写法)

Python 提供 @装饰器名 简化写法,效果和上面完全一样

def my_decorator(func):
    def wrapper():
        print("函数执行前")
        func()
        print("函数执行后")
    return wrapper
# 直接用 @ 装饰
@my_decorator
def say_hello():
    print("Hello 装饰器!")
say_hello()

装饰 带参数的函数

如果原函数有参数,装饰器内部的 wrapper 必须能接收参数,用 *args, **kwargs 通用接收:

def my_decorator(func):
    # wrapper 接收任意参数,传给原函数
    def wrapper(*args, **kwargs):
        print("执行前")
        # 调用原函数并传参
        result = func(*args, **kwargs)
        print("执行后")
        # 返回原函数的返回值
        return result
    return wrapper
@my_decorator
def add(a, b):
    return a + b
print(add(10, 20))

输出

执行前
执行后
30

带参数的装饰器(进阶)

装饰器本身也可以接收参数,需要再套一层函数

# 最外层:接收装饰器参数
def decorator_with_param(msg):
    # 中层:真正的装饰器
    def my_decorator(func):
        # 内层:包装函数
        def wrapper(*args, **kwargs):
            print(f"装饰器参数:{msg}")
            result = func(*args, **kwargs)
            return result
        return wrapper
    return my_decorator
# 使用:装饰器带参数
@decorator_with_param("我是自定义参数")
def test():
    print("原函数执行")
test()

保留原函数信息(重要)

直接使用装饰器会覆盖原函数的名字、文档字符串,需要用 functools.wraps 修复:

import functools
def my_decorator(func):
    # 保留原函数信息
    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        print("前置功能")
        return func(*args, **kwargs)
    return wrapper
@my_decorator
def add(a, b):
    """两数相加"""
    return a + b
# 打印原函数名和文档,不会被装饰器覆盖
print(add.__name__)  # 输出 add
print(add.__doc__)   # 输出 两数相加

实战:最常用的 2 个装饰器

计时装饰器(统计函数运行时间)

import time
import functools
def timer(func):
    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        start = time.time()
        res = func(*args, **kwargs)
        end = time.time()
        print(f"函数 {func.__name__} 耗时:{end - start:.4f}s")
        return res
    return wrapper
@timer
def long_task():
    time.sleep(1)
long_task()

日志装饰器(记录函数调用)

import functools
def logger(func):
    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        print(f"调用函数:{func.__name__},参数:{args} {kwargs}")
        res = func(*args, **kwargs)
        print(f"函数返回:{res}")
        return res
    return wrapper
@logger
def add(a, b):
    return a + b
add(5, 3)

多个装饰器叠加

多个装饰器执行顺序:从下往上装饰,从上往下执行

def dec1(func):
    def wrapper():
        print("装饰器1 前置")
        func()
        print("装饰器1 后置")
    return wrapper
def dec2(func):
    def wrapper():
        print("装饰器2 前置")
        func()
        print("装饰器2 后置")
    return wrapper
# 执行顺序:dec1前置 → dec2前置 → 原函数 → dec2后置 → dec1后置
@dec1
@dec2
def test():
    print("原函数")
test()

总结

  1. 装饰器作用:不修改原函数,动态添加功能(开闭原则)
  2. 核心结构:外层=装饰器,内层=包装函数(真正执行)
  3. 通用写法*args, **kwargs + functools.wraps
  4. 常用场景:计时、日志、权限、缓存、路由(Flask/Django)

到此这篇关于Python装饰器超详细实例教程的文章就介绍到这了,更多相关Python装饰器内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Python matplotlib实战之雷达图绘制

    Python matplotlib实战之雷达图绘制

    雷达图(Radar Chart),也被称为蛛网图或星型图,是一种用于可视化多个变量之间关系的图表形式,本文主要为大家介绍了如何使用Matplotlib绘制雷达图,需要的小伙伴可以参考下
    2023-08-08
  • 基于Python实现向指定PDF指定页面指定位置插入图片的方法

    基于Python实现向指定PDF指定页面指定位置插入图片的方法

    这篇文章主要介绍了使用Python批量为PDF添加虚拟章的方法,通过ReportLab创建覆盖层并结合PyPDF2实现精准合并,确保不破坏原有分辨率和文字可识别性,同时支持位置自定义与参数调整,需要的朋友可以参考下
    2025-09-09
  • 举例讲解Python装饰器

    举例讲解Python装饰器

    这篇文章主要介绍了Python装饰器的相关资料,帮助大家更好的理解和使用python,感兴趣的朋友可以了解下
    2020-12-12
  • Python利用OpenCV和skimage实现图像边缘检测

    Python利用OpenCV和skimage实现图像边缘检测

    提取图片的边缘信息是底层数字图像处理的基本任务之一。本文将通过OpenCV和skimage的 Canny 算法实现图像边缘检测,感兴趣的可以了解一下
    2022-12-12
  • Python cookbook(字符串与文本)在字符串的开头或结尾处进行文本匹配操作

    Python cookbook(字符串与文本)在字符串的开头或结尾处进行文本匹配操作

    这篇文章主要介绍了Python cookbook(字符串与文本)在字符串的开头或结尾处进行文本匹配操作,涉及Python使用str.startswith()和str.endswith()方法针对字符串开始或结尾处特定文本匹配操作相关实现技巧,需要的朋友可以参考下
    2018-04-04
  • python抓取文件夹的所有文件

    python抓取文件夹的所有文件

    这篇文章主要为大家详细介绍了python抓取文件夹的所有文件,包括子文件夹和子文件夹的文件,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-02-02
  • TensorFlow2.X使用图片制作简单的数据集训练模型

    TensorFlow2.X使用图片制作简单的数据集训练模型

    这篇文章主要介绍了TensorFlow2.X使用图片制作简单的数据集训练模型,本文通过截图实例代码相结合给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-04-04
  • Python爬虫代理IP池实现方法

    Python爬虫代理IP池实现方法

    在公司做分布式深网爬虫,搭建了一套稳定的代理池服务,为上千个爬虫提供有效的代理,保证各个爬虫拿到的都是对应网站有效的代理IP,从而保证爬虫快速稳定的运行,所以就想利用一些免费的资源搞一个简单的代理池服务。
    2017-01-01
  • 利用Python实现获取照片位置信息

    利用Python实现获取照片位置信息

    Python中的exifread库,不仅仅是 GPS 信息,几乎能获得图片的所有信息。本文就将利用这个库实现获取照片位置信息,感兴趣的可以了解一下
    2022-08-08
  • Python实现自动发送邮件功能

    Python实现自动发送邮件功能

    这篇文章主要为大家详细介绍了Python实现自动发送邮件功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-12-12

最新评论