python中的 迭代器和生成器
迭代器协议 是__iter__
迭代器是访问集合内元素的一种方式,一般是用来遍历数据的
for 是背后的迭代器在产生作用,
迭代器和以下标的访问方式不一样,迭代器是不能返回的,迭代器提供了一种惰性访问数据的方式
[]使用下标的访问方式,是使用__getitem__
from collections.abc import Iterable,Iterator
重点放在 Iterator 上
*****************************************************************************
class Iterable(metaclass=ABCMeta):
__slots__ = ()
@abstractmethod
def __iter__(self):
while False:
yield None
@classmethod
def __subclasshook__(cls, C):
if cls is Iterable:
return _check_methods(C, "__iter__")
return NotImplemented
*****************************************************************************
class Iterator(Iterable):
__slots__ = ()
@abstractmethod
def __next__(self):
'Return the next item from the iterator. When exhausted, raise StopIteration'
raise StopIteration
def __iter__(self):
return self
@classmethod
def __subclasshook__(cls, C):
if cls is Iterator:
return _check_methods(C, '__iter__', '__next__')
return NotImplemented
*****************************************************************************
from collections.abc import Iterable,Iterator
a = [,]
iter_rator = iter(a)
print(isinstance(a,Iterator))
print(isinstance(iter_rator,Iterator))
print(isinstance(a,Iterable))
>> False
>> True
>> True
a是list ,list不是一个迭代器,但是list是可迭代的,迭代器不支持切片
自己定义可迭代的对象
from collections.abc import Iterator
class Company(object):
def __init__(self,employee_list):
self.employee = employee_list
def __iter__(self):
return MyIterator(self.employee)
class MyIterator(Iterator):
def __init__(self,employee_list):
self.iter_list = employee_list
self.index =
def __next__(self):
try:
word = self.iter_list[self.index]
except IndexError:
raise StopIteration
self.index +=
return word
if __name__ == "__main__":
company = Company(["1","2","3"])
my_itor = iter(company)
for item in company:
print(item)
>>
>>
>>
生成器函数,函数里只要有yield关键字,这就是一个生成器函数,不是普通的函数了
生成器函数 返回的是 一个生成器对象
def gen_func():
yield
def func():
return
if __name__ == "__main__":
gen = gen_func()
re = func()
pass
在 "pass" 处进行debug 的结果:
gen = {generator}<generator object gen_func at >
re = {int}
对代码进行改进:
if __name__ == "__main__":
gen = gen_func()
for value in gen:
print(value)
>>
yield 是 连续返回,实现的是迭代器协议,非常精妙的设计,惰性求值,
或者称为延迟求值,提供可能
def fib(index):
if index <= :
return
else:
return fib(index-)+fib(index-)
print(fib())
def fib1(index):
re_list = []
n,a,b =,,
while n<index:
re_list.append(b)
a,b = b,a+b
n = n+
return re_list
print(fib1())
def gen_fib(index):
n,a,b =,,
while n<index:
yield b
a,b = b,a+b
n = n+
for data in gen_fib():
print(data)
>>
>> [, , , , , , , , , ]
>>
>>
>>
>>
>>
>>
>>
>>
>>
生成器的原理
python的解释器是由C语言来写的,会用一个叫做 pyEval_EvalFramEx(C函数)去执行foo函数,首先会创建一个栈帧(stack_frame),栈帧对象,字节码对象,