1.迭代器
# 2.可迭代对象
# 可以通过for循环取值的对象,我们称之为可迭代对象
# str/list/tuple/dict/set
# li = {1, 2, 3} # 集合
# # print(type(li))
#
# for i in li: # in的后面是可迭代对象
# print(i)
# 可迭代对象: Iterable
# 泛指一类对象,满足以下条件的都可以成为可迭代对象:
# 1.对象实现了__iter__方法
# 2.__iter__方法返回了一个迭代器对象
# 如何判断一个对象是否可以迭代
# 什么是迭代:对这些数据使用for循环,从里面依次取到值来进行使用,这样的过程称为遍历,也叫迭代。
# isinstance() : 判断对象是否是Iterable对象, 是可迭代对象就返回为True, 否为False
# from collections.abc import Iterable
# print(isinstance([1, 2], Iterable)) # 对象, 可迭代对象
# print(isinstance(10, Iterable))
# print(isinstance(('a', 'b'), Iterable))
# 3.迭代器 Iterator
# 3.1 iter()函数 和 next()函数
# li = ['a', 'b', 'c'] # 列表是可迭代对象
# 1.创建迭代器对象, 通过iter()把li变成迭代器对象
# it = iter(li)
# print(it) # 返回的是迭代器对象
# 2.输出迭代器的下一个元素
# print(next(it))
# print(next(it))
# print(next(it))
# print(next(it)) # 3.取完元素后,再使用会引发StopIteration异常
# 3.2 __iter__方法和__next___方法
# tu = (1, 2, 3)
# tu2 = tu.__iter__()
# print(tu2)
# print(tu2.__next__())
# print(tu2.__next__())
# print(tu2.__next__())
# print(tu2.__next__())
# 3.3
# xi = {'唐僧', '悟空', '八戒', '沙僧'}
#
# it = iter(xi)
# # print(it)
# try:
# while True:
# print(next(it))
# except Exception:
# print('人满了')
# 4.可迭代对象和迭代器对象
# 可迭代对象:Iterable
# 迭代器对象:Iterator
# 凡是可以for循环的是属于可迭代对象
# 凡是可以使用next方法的是迭代器
# from collections.abc import Iterable, Iterator
# s = [1, 2]
# print(isinstance(s, Iterable)) # 是可迭代对象
# print(isinstance(s, Iterator)) # 不是迭代器对象
# print('---'*20)
# s2 = iter(s) # 转换为迭代器对象
# print(isinstance(s2, Iterable)) # 是可迭代对象
# print(isinstance(s2, Iterator)) # 是迭代器对象
# 迭代器对象一定是可迭代对象,而可迭代对象不一定是迭代器对象
# 5.总结
# 5.1 可迭代对象可以通过iter方法变成迭代器对象
# 5.2 如果一个对象拥有iter方法,是可迭代对象;如果一个对象拥有next方法,是迭代器对象
# 5.3 定义可迭代对象,必须实现iter方法; 定义迭代器,必须实现iter和next方法
2.迭代器协议
# 1.迭代器协议:
# 迭代器对象是实现了迭代器协议的对象
# 概念:
# 对象必须提供一个next方法,执行该方法要么返回迭代中的下一项,
# 要么就引起一个StopIteration异常,来终止迭代。
# 条件:
# 1.对象实现了next方法
# 2.next方法返回了某个数值
# 3.取完值以后,抛出StopIteration异常
# 自定义迭代器类
# 1.有__iter__()方法,返回迭代器本身
# 2.有__next__()方法,返回对象的下一个元素或抛出StopIteration异常
# 3.如果在一个类中定义__iter__()方法,那么类的实例就是一个迭代器。
# iter方法需要返回一个迭代器,返回对象本身即可(返回self)
# class A:
# def __iter__(self):
# self.n = 0
# return self # 返回实例对象本身,自身就是自己的迭代器
#
# def __next__(self): # 实例方法
# self.n += 1
# return self.n
# a = A() # 实例化对象
# my = iter(a)
# print(my)
# print(next(my))
# print(next(my))
# print(next(my))
# for i in a:
# if i <= 4:
# print(i)
# else:
# break
# class Test:
# def __init__(self):
# self.n = 0
#
# def __iter__(self):
# return self
#
# def __next__(self):
# if self.n == 3:
# raise StopIteration('终止了')
# self.n += 1
# return self.n
#
#
# te = Test()
# print(te)
# print(te.__iter__())
# for i in te:
# print(i)
# print(next(te))
# print(next(te))
# print(next(te))
# print(next(te))
3.生成器
# 可迭代对象/迭代器
# 生成器: generator
# 生成器本质是迭代器
# 1.生成器函数:常规函数的定义,使用yield语句,
# 而不是return语句返回结果
# yield语句一次返回一个结果,在每个结果中间,
# 挂起函数的状态,方便下次从它离开的位置继续执行
# 2.怎么创建生成器
# 2.1 生成器表达式
# li = [0, 1, 2] # 每个元素乘以2,得出新的结果
#
# li2 = [i*2 for i in range(3)] # 列表推导式
# li2 = [i*2 for i in li]
# print(li2)
# li3 = (i*2 for i in range(3)) # 生成器表达式
# print(li3)
# print(next(li3))
# print(next(li3))
# print(next(li3))
# for i in li3:
# print(i)
# 2.2 生成器函数
# def funa():
# print('开始--')
# yield 'jiuge'
# yield 'a' # 返回一个'a', 并暂停函数
# yield 'b'
# fa = funa() # 调用一个生成器函数
# print(fa) # 返回的是一个迭代器对象
# print(next(fa))
# print(next(fa))
# print(next(fa))
# for i in fa:
# print(i)
# 3. return 和 yield
# 3.1 相同点:都是返回函数执行的结果
# 3.2 return 返回结果后函数结束;
# yield 让函数变成一个生成器,每次会产生一个值,保存中断状态,被唤醒后再产生一个值
# def funb():
# yield 123
#
# fb = funb()
# print(next(fb))
# print(next(fb))
# def funb():
# yield 123
# yield 456
# return '这是return' # return后返回值,这个值变成了StopIteration异常的说明
#
# fb = funb()
# print(next(fb))
# print(next(fb))
# print(next(fb))
# 4. 举例
# with open('we.txt', 'w', encoding='utf-8') as file:
# file.write('这是一个文件')
# def check(fname, word): # fname是文件名, word是查找的内容
# with open(fname, encoding='utf-8') as file:
# # print(file.read())
# for f in file:
# # print(f)
# if word in f:
# yield f
#
# ch = check('we.txt', '生成器')
# print(next(ch))
# ctrl+/ : 取消注释、注释
# def test(): # 生成器函数
# n = 0 # 初始值
# while True:
# if n < 3: # n : 0 1 2
# yield n
# n += 1
# else:
# yield '错误了'
#
# t = test()
# print(next(t))
# print(next(t))
# print(next(t))
# print(next(t))
# print(next(t))
# print(next(t))
# for i in range(4):
# print(next(t))