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。
验证方法
dir()查看是否含_iter_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、set | list 迭代器、文件对象 |
四、总结
函数名:Python 第一类对象,支持赋值、传参、返回值,灵活扩展函数功能;
闭包:内层引用外层变量 + 返回内层函数,核心价值是变量常驻内存;
迭代器:基于
\_\_iter\_\_和\_\_next\_\_,惰性遍历节省内存,for循环底层依赖迭代器;核心区别:可迭代对象是 “数据容器”,迭代器是 “数据生成器”。
