Python闭包原理与常见陷阱解析

小岛来信
小岛来信
发布时间:2026-10-13| 3人浏览过
原创

本文深入解析Python中闭包的定义与工作机制,重点剖析循环中返回函数时变量引用导致的常见错误。通过对比错误代码与修正方案,阐明如何利用参数绑定解决循环变量共享问题,为理解装饰器及高级函数编程奠定基础。

闭包概念概述

一、闭包概念概述

闭包的核心定义在于:当内部函数引用了外部函数的参数或局部变量,且该内部函数作为返回值被返回时,这些外部变量和参数会随同内部函数一起被保存下来。这种将变量与函数绑定在一起的结果,即被称为闭包。

在前文连载的第17部分中,示例函数myF4展示了这一机制的典型应用。

闭包常见陷阱与解决方案

三、闭包使用中常见的误区


def count():
  #定义列表
fs = []
for i in range(1, 4):
  def f():
  return i * i
fs.append(f)
# 按照我们的预期, 应该是fs = [f, f, f].其中f中一次包含1, 4, 9, 这样才对, 但实际结果不是, 我么接着看
return fs
f1, f2, f3 = count()
print(f1(), f2(), f3())

预期的输出结果并非1、4、9。

(1)原因剖析:返回的函数实际上引用的是变量i,但i并未在定义时立即执行。直到三个函数全部返回后,才统一执行计算,此时变量i的值已变为3,因此最终调用时返回的是3*3的结果。

(2)核心结论:在返回闭包时,内部函数不应直接引用任何循环变量。

(3)解决策略:引入一个额外的函数,利用该函数的参数来绑定循环变量的当前值。由于参数在调用时即被固定,无论后续循环变量如何变化,已绑定的函数参数值保持不变。

改进后的代码如下:


def count2():
  def f(j):
    def g():
      return j*j
    return g
  fs = []
  for i in range(1,4):
    fs.append(f(i))
    #我们进行了传参,因此j就固定下来,它就执行了j
  return fs
f4,f5,f6 = count2()
print(f4(),f5(),f6())

装饰器与源码参考

二、装饰器简介


def hello():
  print("我是一个程序")
f = hello
f()
hello()
#用id来证明f和hello是一个函数
print(id(f),id(hello))

三、完整源代码

项目目录:d20_2_closure_interpretation

代码仓库地址:https://github.com/ruigege66/Python_learning/blob/master/d20_2_closure_interpretation

文中通过详细的示例代码进行了介绍,对读者的学习或工作具有较高的参考价值。

相关标签:

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

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 算法库。