ChuannBlog

3.4 生成器

判断是不是迭代器:

  1. 查看对象内部是否使用了__iter__和__next__方法 in dir(obj)
  2. 导入collections的Iterator,查看对象是否是迭代器
    • iter() iterable 可迭代的

      str
      list
      tuple
      set
      dict

    • 可迭代协议:
      • 可迭代对象内部都有一个__iter__方法
    • 迭代器协议:
      • 迭代器内部既有__iter__方法,也有__next__
      • 迭代器大部分都是在python的内部去使用的,通常都会封装成各种内置方法
     # '__length_hint__', '__next__', '__setstate__'
     a = [1, 2]
     b = a.__iter__()
     # print(a.__iter__())
     print(b.__length_hint__())
     print(b.__next__())
     print(b.__next__())
     # print(b.__next__())
     print(b.__setstate__(0))
    
    • __length_hint__ 计算迭代器的长度
    • __next__

    • __setstate__ 设置迭代器的起始位置 - next()
from collections import Iterable
from collections import Iterator

a = [1, 2, 3, 4, 5, 6]
print(isinstance(a, Iterable))
print(isinstance(a, Iterator))
print(isinstance(iter(a), Iterator))

迭代器的优点

迭代器并不会真的保存一个全部的结构,而是一个个读一个个取
不依赖索引,节省内存空间,惰性计算

可迭代对象:

  拥有__iter__方法

  特点:惰性运算

  例如:range(),str,list,tuple,dict,set

迭代器Iterator:

  拥有__iter__方法和__next__方法

  例如:iter(range()),iter(str),iter(list),iter(tuple),iter(dict),iter(set),reversed(list_o),map(func,list_o),filter(func,list_o),file_o(文件句柄)

生成器和列表推导式

本质是迭代器,自带iter和next方法
提供给用户用于生成自定义的迭代器

生成器函数

def func():
    aa = 1
	yield aa
    print('aa')
	aa = 2
    yield aa

ret = func()
print(ret)
print(next(ret))
import time
def tail(filename):
    with open(filename, 'r') as rf:
        rf.seek(0, 2)
        while True:
            line = rf.readline()
            if not line:
                time.sleep(0.1)
                continue
            yield line

for line2 in tail('test'):
    print(line2, end='')
for i in iterable:
    yield i

扩展阅读

进阶