Python闭包与装饰器底层机制详解

沈亦白
沈亦白
发布时间:2026-10-14| 6人浏览过
原创

本文深入解析Python中闭包的构成条件及其在装饰器中的应用。通过代码示例说明自由变量的生命周期管理,并重点讲解装饰器导致函数元信息丢失的问题及利用functools.wraps修复的方法,附带带时间统计功能的装饰器实现代码。

Python闭包的构成条件与原理

一、闭包

从结构上看,闭包是指在外部函数内部定义一个内部函数,且该内部函数引用了外部函数的变量,这类被引用的变量被称为自由变量。

本质上,闭包是将函数代码语句与其执行时的环境状态打包在一起形成的对象。

构建闭包需要满足以下三个条件:

必须存在一个内嵌函数。

该内嵌函数必须使用外部函数的变量。

外部函数的返回值必须是这个内嵌函数。


def closure():
 value = []
 def fun(tmp):
  value.append(tmp)
  return value
 return fun

cc = closure() 
cc(0) #[0] 等同于closure(fun(0))
cc(1) #[0,1]
cc(2) #[0,1,2]

在外部函数closure中,变量value与内部函数fun共同存在,且fun引用了自由变量value。当执行cc = closure()时,便生成了一个闭包对象fun。该闭包持有了变量value的引用,即使外部函数closure执行完毕,value依然存在于内存中,因为闭包对其进行了引用。

装饰器的实现与元信息处理

二、装饰器

装饰器本质上是闭包的一种具体应用形式,其传递和处理的目标是函数对象。


def add_time(fun):
 def wrapper():
  print('time: 12:00')
  return fun()
 return wrapper

def add_format(fun):
 def wrapper():
  print('\n')
  return fun()
 return wrapper

@add_format #等同于demo = add_format(add_time(demo))
@add_time #等同于 demo = add_time(demo)
def demo():
 return 'hello world!'

需要注意的是,直接使用装饰器会导致原函数的元信息(如__name__等属性)丢失。

例如,原函数demo的__name__属性在装饰后会变为wrapper。为解决此问题,需引入functools库,在wrapper函数定义前添加@functools.wraps(fun)装饰器:


import functools

def add_time(fun):
 @functools.wraps(fun)
 def wrapper():
  print('time: 12:00')
  return fun()
 return wrapper

def add_format(fun):
 @functools.wraps(fun)
 def wrapper():
  print('\n')
  return fun()
 return wrapper

@add_format #等同于demo = add_format(add_time(demo))
@add_time #等同于 demo = add_time(demo)
def demo():
 return 'hello world!'

以下示例展示如何编写一个为任意函数添加打印时间功能的装饰器:


def metric(fn):
 start=time.time()
 @functools.wraps(fn)
 def wrapper(*args,**kw):
  end=time.time()
  print('%s executed in %s ms' % (fn.__name__,start-end))
  return fn(*args,**kw)
 return wrapper

以上内容涵盖了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 算法库。