Python中的闭包与迭代器
前面内容补充
函数名分应用(第一类对象)
函数名的命名规范与变量命名是一样的
函数名其实就是变量名
函数名可以作为列表中的元素进行存储
例如:
1 def func1(): 2 pass 3 def func2(): 4 pass 5 def func3(): 6 pass 7 8 lis = [func1,func2,func3] 9 for el in lis: 10 el()
可以作为参数传递给函数,
def func(): pass def proxy(fu): fu() proxy(func)
可以作为函数的返回值
1 def func(): 2 def inner(): 3 pass 4 return inner 5 ret = func() 6 ret() 7 同 8 func()()
二 闭包
闭包: 在内层函数中访问外层函数的局部函数的局部变量
简易写法:
def func(): a = 10 def inner(): print(a) return inner
作用 :
1 保护你的变量不收外界影响
2 可以让变量常驻内存
例如: 超简易的爬虫
from urllib.request import urlopen def outer(): s = urlopen("http://www.xiaohua100.cn/index.html").read() #常驻内存 def getContent(): return s #闭包 return getContent print("爬取内容") pa = outer() ret = pa() print(ret) 主要体现是闭包的常驻内存 方便以后调用
判断是否为闭包
写法格式:
_closure_
里面的函数名._closure_ 如果打印的是None 则不是闭包, 如果打印的不是None 则是闭包
1 def outer(): 2 a = 10 3 def func(): 4 print(a) 5 print(func.__closure__) # 查看该函数是不是闭包 6 outer() 7 8 9 结果: 10 (<cell at 0x000002A3B8817588: int object at 0x000000006AAC6D40>,)
三 迭代器
使用dir来查看该数据包含了那些方法
例如:
print(dir(list)) 结果 ['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']
dir 查看XX类型的数据可以执行哪些方法, _iter_ () iterable
所有带_iter_ 都是可以使用for循环的 可以迭代的对象
可迭代的对象: Iterable , 里面有_iter_() 可以获取迭代器,没有_next_()
迭代器: 是用来遍历列表,字符串,元组,.......... 可迭代的对象
迭代器 : Iterator , 里面有 _iter_() 可以获取迭代器 里面还有_next_() 将可迭代对象迭代
s = "我听见冬天的离开,你在某时某刻醒过来" it = s.__iter__() # 获取迭代器 print(dir(it)) # 迭代器里有__iter__ 还有__next__ 结果 ['__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__length_hint__', '__lt__', '__ne__', '__new__', '__next__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setstate__', '__sizeof__', '__str__', '__subclasshook__']
迭代器的特点:
1 只能向前
2 惰性机制
3 省内存
for 循环内部机制
1 首先获取到迭代器
2 使用while循环获取数据
3 it._next_()来获取数据
4 处理异常 try:xxx except StopIteratio:
迭代器模拟for循环
# 迭代器模拟for循环 lis = ["王尼玛","狗哥","熊大","小眼","小猪","胡大宇"] it = lis.__iter__() while 1 : try: # 尝试执行 print(it.__next__()) #获取下一个元素 except StopIteration: # 处理错误 break
判断数据是否是可迭代的, 以及数据是否是迭代器
偏方
lit = ["所以说","永远多长","永远短暂","永远很遗憾","没个人有每个人不同的计算"]
it = lit.__iter__()
print("__iter__" in dir(it))
print("__next__" in dir(it))
结果
True
True
官方方案
from collections import Iterable # 可迭代对象 from collections import Iterator # 迭代器 print(isinstance(lit,Iterable)) print(isinstance(lit,Iterator)) print(isinstance(it,Iterable)) print(isinstance(it,Iterator))
list() 也能循环迭代
lit = ["所以说","永远多长","永远短暂","永远很遗憾","每个人有每个人不同的计算"] it = lit.__iter__() # list(参数)把参数进行循环迭代 s = list(it) # 在list中,一定存在for,一定有__next__() print(s) 结果 ['所以说', '永远多长', '永远短暂', '永远很遗憾', '每个人有每个人不同的计算']