Python装饰器详解:从闭包到类装饰器的完整指南

栗子
栗子
发布时间:2026-10-15| 4人浏览过
原创

本文深入解析Python装饰器的核心原理,从闭包的基础概念讲起,逐步演示无参、带参及类装饰器的具体实现。通过实际代码案例,展示如何在无需修改原函数代码的前提下,为函数添加调试、日志记录等额外功能,帮助开发者掌握装饰器的灵活应用技巧。

一、闭包

理解装饰器的前提是掌握闭包这一概念。简单来说,闭包是指在函数内部定义另一个函数,且内部函数引用了外部函数的变量。为了直观理解,我们直接通过代码示例来说明。


def outer(x):
    def inner(y):
        return x + y
    return inner

print(outer(6)(5))
-----------------------------
>>>11

如代码所示,在outer函数内部定义了inner函数,且inner函数引用了外部函数outer的变量x,这构成了一个闭包。执行outer(6)(5)时,第一个括号传入的值返回inner函数,即返回6 + y的逻辑,因此再传入第二个参数即可得到最终返回值6 + 5。

二、装饰器

接下来介绍装饰器,其实装饰器本质上就是一个闭包,它是闭包的一种具体应用。所谓装饰器,简单来说就是用于扩展原函数功能的一种函数,其特殊之处在于返回值仍然是一个函数。使用Python装饰器的好处在于,无需修改原函数的代码即可为其增加新功能。使用时,只需在目标函数前加上@demo即可。


def debug(func):
    def wrapper():
        print("[DEBUG]: enter {}()".format(func.__name__))
        return func()
    return wrapper

@debug
def hello():
    print("hello")

hello()
-----------------------------
>>>[DEBUG]: enter hello()
>>>hello

示例中的装饰器为函数添加了进入时的debug模式,无需修改原函数代码便实现了该功能,非常便捷。

三、带参数的装饰器

上述示例中的装饰器功能较为简单,那么装饰器是否可以接收参数呢?答案是可以的。此外,被装饰的函数同样可以传递参数。


def logging(level):
    def outwrapper(func):
        def wrapper(*args, **kwargs):
            print("[{0}]: enter {1}()".format(level, func.__name__))
            return func(*args, **kwargs)
        return wrapper
    return outwrapper

@logging(level="INFO")
def hello(a, b, c):
    print(a, b, c)

hello("hello,","good","morning")
-----------------------------
>>>[INFO]: enter hello()
>>>hello, good morning

如上所示,装饰器中可以传入参数,先构建一个完整的装饰器,然后再用于装饰函数。如果被装饰的函数需要传入参数,也可以使用不定长参数符号来接收,示例中传入了三个参数。

四、类装饰器

装饰器不仅可以用函数编写,还可以使用类来实现,即类装饰器。其用法与函数装饰器没有太大区别,实质是利用类方法中的__call__魔法方法来实现类的直接调用。


class logging(object):
    def __init__(self, func):
        self.func = func

    def __call__(self, *args, **kwargs):
        print("[DEBUG]: enter {}()".format(self.func.__name__))
        return self.func(*args, **kwargs)

@logging
def hello(a, b, c):
    print(a, b, c)

hello("hello,","good","morning")
-----------------------------
>>>[DEBUG]: enter hello()
>>>hello, good morning

类装饰器同样可以携带参数,如下所示的实现方式。


class logging(object):
    def __init__(self, level):
        self.level = level

    def __call__(self, func):
        def wrapper(*args, **kwargs):
            print("[{0}]: enter {1}()".format(self.level, func.__name__))
            return func(*args, **kwargs)
        return wrapper
        
@logging(level="TEST")
def hello(a, b, c):
    print(a, b, c)

hello("hello,","good","morning")
-----------------------------
>>>[TEST]: enter hello()
>>>hello, good morning

以上就是装饰器的一些基本概念和大致用法。若想更深入地理解装饰器,还需要在日常练习和应用中多加体会。

以上就是如何正确理解python装饰器的详细内容,更多关于python装饰器的资料请关注本站其它相关文章!

相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。