当前位置: 首页 > news >正文

Python 进阶:函数名、闭包与迭代器

摘要

本文聚焦 Python 进阶核心知识点,详细讲解函数名的第一类对象特性闭包的定义、检测与应用迭代器与可迭代对象的本质区别及工作原理,附完整可运行代码示例,帮助开发者夯实 Python 进阶基础,理解底层执行逻辑。


一、函数名的运用(第一类对象)

Python 中函数是第一类对象,函数名本质是特殊变量,具备赋值、传参、作为返回值等特性。

1. 函数名的内存地址

直接打印函数名,可查看其内存地址,验证函数名是变量:

def func(): print("呵呵") ​ # 打印函数内存地址 print(func) # 输出:<function func at 0x1101e4ea0>

2. 函数名赋值给其他变量

可将函数名赋值给新变量,通过新变量调用原函数:

def func(): print("呵呵") ​ # 函数名赋值 a = func # 通过新变量调用函数 a() # 输出:呵呵

3. 函数名作为容器元素

函数名可存入列表、元组等容器,遍历容器即可批量执行函数:

def func1(): print("执行函数1") ​ def func2(): print("执行函数2") ​ def func3(): print("执行函数3") ​ # 函数名存入列表 lst = [func1, func2, func3] # 遍历执行 for i in lst: i()

4. 函数名作为函数参数

将函数作为参数传递给另一个函数,实现函数间的灵活调用:

def func(): print("吃了么") ​ # 接收函数作为参数 def func2(fn): print("我是func2") # 执行传入的函数 fn() ​ # 传递函数名 func2(func)

5. 函数名作为函数返回值

函数可返回另一个函数(嵌套函数),实现延迟调用:

def func_1(): print("这里是函数1") # 内部函数 def func_2(): print("这里是函数2") # 返回内部函数名 return func_2 ​ # 接收返回的函数 fn = func_1() # 调用内部函数 fn()

二、闭包

1. 闭包定义

闭包:内层函数引用外层函数(非全局)变量,且外层函数返回内层函数,形成的嵌套函数结构。

2. 基础示例

def func1(): # 外层函数变量 name = "alex" # 内层函数(闭包) def func2(): # 引用外层变量 print(name) return func2 ​ # 调用外层函数,获取内层函数 fn = func1() # 执行内层函数 fn() # 输出:alex

3. 闭包检测:closure

通过函数的closure属性检测是否为闭包:

  • 返回cell对象:是闭包

  • 返回None:不是闭包

def func1(): name = "alex" def func2(): print(name) return func2 ​ fn = func1() # 检测闭包 print(fn.__closure__) # 输出:(<cell at 0x10c2e20a8: str object at 0x10c3fc650>,)

4. 外部调用内部函数

闭包核心作用:在函数外部访问内部函数

def outer(): name = "alex" # 内部函数 def inner(): print(name) return inner ​ # 外部获取内部函数地址 fn = outer() # 外部调用内部函数 fn() # 输出:alex

5. 多层嵌套闭包

多层嵌套只需逐层返回内层函数:

def func1(): def func2(): def func3(): print("嘿嘿") return func3 return func2 ​ # 逐层调用 func1()()() # 输出:嘿嘿

6. 闭包的核心作用

闭包让外层函数变量常驻内存,避免函数执行后变量销毁,适合耗时操作缓存场景(如爬虫):

from urllib.request import urlopen ​ def but(): # 耗时网络请求(仅执行1次) content = urlopen("http://www.xiaohua100.cn/index.html").read() def get_content(): # 直接返回缓存内容 return content return get_content ​ # 首次调用:执行网络请求 fn = but() # 后续调用:直接读取缓存,无需重复请求 content1 = fn() content2 = fn()

三、迭代器

1. 可迭代对象(Iterable)

定义

内部实现_iter_()方法的对象,可通过for循环遍历,常见:str、list、tuple、dict、set、range

验证方法
  1. dir()查看是否含_iter_

  2. isinstance()判断类型

from collections import Iterable ​ # 方法1:dir()查看 s = "测试字符串" print("__iter__" in dir(s)) # True ​ # 方法2:isinstance() lst = [1,2,3] print(isinstance(lst, Iterable)) # True print(isinstance(123, Iterable)) # False(int不可迭代)

2. 迭代器(Iterator)

定义

同时实现_iter_(\)_next_\(\)方法的对象,是可迭代对象的进阶

核心特性
  • 惰性机制:不一次性加载所有数据,节省内存

  • 单向执行:只能向下遍历,不可回退

  • 一次性:遍历结束后不可重复使用

验证迭代器
from collections import Iterator ​ lst = [1,2,3] # 获取迭代器 lst_iter = lst.__iter__() ​ print(isinstance(lst, Iterator)) # False print(isinstance(lst_iter, Iterator))# True

3. 迭代器工作原理

通过_iter_(\)获取迭代器,_next_(\)逐个获取元素,无元素时抛出StopIteration异常。

基础示例
s = "我爱北京天安门" # 获取迭代器 c = s.__iter__() ​ # 逐个获取元素 print(c.__next__()) # 我 print(c.__next__()) # 爱 print(c.__next__()) # 北 print(c.__next__()) # 京 # 无元素时抛出异常 # print(c.__next__()) # StopIteration
模拟 for 循环(必掌握)

for循环底层是迭代器 + 异常捕获的封装:

lst = [1,2,3] # 获取迭代器 lst_iter = lst.__iter__() ​ # while循环模拟for while True: try: # 获取元素 i = lst_iter.__next__() print(i) # 捕获结束异常 except StopIteration: break

4. Iterable vs Iterator 对比表

特性可迭代对象(Iterable)迭代器(Iterator)
核心方法_iter_(\)_iter_(\)+_next_(\)
内存占用一次性加载,占用大惰性加载,占用小
遍历次数可重复遍历仅一次遍历
典型对象list、str、dict、setlist 迭代器、文件对象

四、总结

  1. 函数名:Python 第一类对象,支持赋值、传参、返回值,灵活扩展函数功能;

  2. 闭包:内层引用外层变量 + 返回内层函数,核心价值是变量常驻内存

  3. 迭代器:基于\_\_iter\_\_\_\_next\_\_,惰性遍历节省内存,for循环底层依赖迭代器;

  4. 核心区别:可迭代对象是 “数据容器”,迭代器是 “数据生成器”。

http://www.gsyq.cn/news/1429858.html

相关文章:

  • 069、NeRF/Gaussian Splatting 训练太慢?数据预处理、加速采样与低分辨率预热方案
  • 3PEAK思瑞浦 TP2191-TR SOT23-5 运算放大器
  • Hyperf 利用 PHP 的 反射机制的庖丁解牛
  • spi_master
  • 第八届高分子化学国际研讨会 (ICPC 2026)
  • Python类型推导协议
  • 城通网盘解析器:3分钟掌握免费高速下载的终极方案
  • OpencvSharp 算子学习教案之 - Cv2.CvtColor
  • MATLAB图论实战:除了shortestpath,自己写的Dijkstra函数如何优化与可视化?
  • 3PEAK思瑞浦 TP5551-TR SOT23-5 精密运放
  • OmenSuperHub:彻底释放惠普暗影精灵游戏本性能的终极解决方案
  • OpencvSharp 算子学习教案之 - Cv2.CvtColorTwoPlane
  • 双系统Ubuntu18.04升级22.04,安装docker进行openclaw安装
  • 【电赛保姆级教程】别在比赛时从零写代码了!电赛“祖传代码库”搭建与OLED多级菜单硬核指南
  • 2026年5月AI模型性能排行:代码能力Claude霸榜,智谱GLM杀入前十
  • 调试记录 - 2024年1月15日
  • 告别排版焦虑:西安交大LaTeX论文模板让你专注学术创新
  • 【电赛保姆级教程】别再用L298N了!电赛电机驱动与高阶控制(带FOC扫盲)硬核避坑指南
  • LabVIEW与外部设备通信秘籍:用DLL传递复杂结构体(含数组/嵌套结构)的完整配置流程
  • 那些年,我追Google Trends追到精疲力尽的故事
  • 深入FIO引擎:除了libaio,这些ioengine(如sync, psync, mmap)在Linux下到底怎么选?性能差多少?
  • 口袋神器!Arduino 创客必备,可接入 DeepSeek、Qwen 等 AI 大模型,通过 GPIO 串口控制 IoT 智能设备
  • C# 泛型
  • C++之父开撕AI Coding:资深开发者宁愿退休也不愿伺候AI生成的代码
  • 为什么你的论文参考文献格式总是不对?3个GB/T 7714 BibTeX样式终极解决方案
  • 187、运动控制中的行业应用:机械臂力控打磨
  • 前端内存泄漏常见场景与排查
  • GTA5线上小助手:免费开源工具帮你轻松称霸洛圣都终极指南
  • Kettle官网大变样?别慌!手把手教你找到最新9.3版本的下载入口(附Hadoop Shims获取指南)
  • 【AI+房地产实战指南】:2024年最值得落地的7大智能整合场景与避坑清单