# 可迭代对象:Iterable
# 能被for循环遍历取值的数据类型:list/str/tuple/dict/set
# 遍历(迭代):可迭代对象使用 for i in 可迭代对象:的循环语法从其中依次拿到数据使用的过程
# a="python"
# for i in a: #遍历取值
# print(i)
# 可迭代对象:泛指一类对象, 满足以下条件的对象可以成为可迭代对象:
# 对象实现了__iter__方法
# __iter__方法返回了迭代器对象
# for循环工作原理
# 在内部对可迭代对象调用__iter__方法, 获取到迭代器对象, 再一次次的通过迭代器对象,调用__next__方法获取结果
# isinstance() 判断一个对象是否可以迭代
# 可迭代对象其实都是collections模块里面的Iterable类创建出来的实例
from collections.abc import Iterable # 导入模块
# a="python"
# print(isinstance(a,Iterable )) #结果为True # 该对象是可迭代对象,返回为真
# b=123
# print(isinstance(b,Iterable)) #结果为:False ## 该对象不是可迭代对象,返回为假
# 迭代器-- Iterator
#迭代器是一个可以记住遍历的位置的对象,迭代器对象从集合的第一个元素开始访问,直到所有元素被访问玩,迭代器只能往前不会后退
# 迭代器就是实现了__iter__和 __next__方法的对象
# 迭代器有两个函数: iter() 和 next()
# 遍历取值步骤:
# 先调用对象的iter函数:iter()直接调用该对象的__iter__方法,并把该方法的返回结果作为自己的返回值
# 再使用next()函数来调用__next__方法
# 元素取完后,__next__方法会引发StopIteration异常
#lb=["abc","123456","python","哈哈哈哈"]
# dd=iter(lb) #用函数创建迭代器对象
# #print(dd) #结果为:<list_iterator object at 0x00000221BDD6AF88> 返回内存地址
# print(next(dd)) #结果为:abc 用函数获取列表里的元素
# print(next(dd)) #结果为:123456
# print(next(dd)) #结果为:python
# print(next(dd)) #结果为:哈哈哈哈
# print(next(dd)) # 取完元素后,再去取 引发StopIteration异常
# lb=["abc","123456","python","哈哈哈哈"]
# dd=lb.__iter__()
# try: #捕获异常
# while True:
# print(dd.__next__())
# #结果为:abc
# # 123456
# # python
# # 哈哈哈哈
# # 数据取完
# except :
# print("数据取完")
# 可迭代对象和迭代器对象
# 可迭代对象:Iterable
# 迭代器对象:Iterator
# isinstance()判断的函数
# from collections.abc import Iterable, Iterator # 导入模块
# st = 'python'
# # print(isinstance(st, Iterable)) #结果为: True st是可迭代对象
# # print(isinstance(st, Iterator)) #结果为: False st不是迭代器对象
#
# it = iter(st)
# # print(it) # <str_iterator object at 0x000002397E9F24C8>
# print(isinstance(it, Iterable)) #结果为: True it是可迭代对象
# print(isinstance(it, Iterator)) #结果为: True it是迭代器对象
#迭代器对象一定是可迭代对象,可迭代对象不一定是迭代器对象
# 可迭代对象可以通过方法变成迭代器对象
# 迭代器协议
# 概念:对象必须提供一个next方法,执行该方法要么返回下一项,要么引起StopIteration异常
# 条件:
# 对象实现__next__方法
# next方法放了某个数据
# 数据取完的时候,抛出StopIteration异常
# 迭代器对象是实现了迭代器协议的对象
# 自定义迭代器类
# 需要有两个特性:
# 具有iter方法,返回迭代器对象本身(类中定义了iter方法,这个类的实例就是一个迭代器对象)
# 具有next方法,返回下一个元素或者抛出StopIteration异常
# 自定义类,实例化的对象不能使用for循环遍历取值
# class Test:
# def __init__(self):
# self.n = 0 # 定义一个初始值n
#
# def funa(self): # 实例方法
# # print('这是funa方法')
# self.n += 1
# return self.n
# # 实例化对象
# te = Test()
#
# for i in te: # TypeError: 'Test' object is not iterable
# print(i)
# 修改后,实例对象可以通过for循环遍历取值
# class Test2:
#
# # 返回迭代器对象
# def __iter__(self):
# self.n = 0
# return self # 返回的是当前的实例对象,也就是迭代器对象
#
# # 返回的是要取的数据
# def __next__(self):
# # 第二种:
# if self.n == 6: # 设置条件,n的值为6时,抛出异常
# # 抛出异常
# raise StopIteration('超出范围了')
# self.n += 1
# return self.n
#
#
# te2 = Test2()
# # 直接调用next方法报错,没有调用iter方法,实例属性self.n没有生成
# it = iter(te2)
# while True:
# print(next(it))
# 第一种:
# for循环中加结束条件
# for i in te2:
# if i <= 10:
# print(i)
# else:
# break
# 第二种:
# for i in te2:
# print(i)
#实例一: 打印十次"python"
# class Ddq():
# def __init__(self,x):
# self.x = x
# self.n=0 #结束迭代器的变量
# def __iter__(self): #只要重写了__iter__方法就是一个可迭代对象
# return self
# def __next__(self): #for循环每次都调用__next__方法,获取返回值
# self.n += 1 #每调用一次__next__方法变量就加一
# if self.n <= self.x:
# return "python"
# else :
# raise StopIteration #让迭代器停止
# a=Ddq(10)
# for i in a:
# print(i) #会打印十次python
#实例二:使用迭代器生成斐波那契数列 这个数列从第3项开始,每一项都等于前两项之和, 1 1 2 3 5 8 13 21 .......
# class Series():
# def __init__(self,x):
# self.x=x
# self.n=1
# self.n1=1
# self.n2=0
# def __iter__(self):
# return self
# def __next__(self):
# self.n2+=1
# if self.n2 <= self.x:
# y = self.n
# self.n, self.n1 = self.n1, self.n + self.n1
# return y
# else :
# raise StopIteration
# b=Series(10)
# for i in b:
# print(i)
#生成器函数
# 生成器就是一种自定义的迭代器,本质是迭代器
# 定义方式:生成器表达式:类似列表推导式
#li = [i*2 for i in range(3)] # 列表推导式
# print(li) # [0, 2, 4]
# li2 = (i*2 for i in range(3)) # 生成器表达式
# print(li2) # <generator object <genexpr> at 0x000002631B3A7DC8>
# print(next(li2))
# for i in li2:
# print(i)
#结果为:0
# 2
# 4
# 生成器函数
# yield:每次返回一个结果,在每个结果中间,挂起函数,以便下次从它离开的地方继续执行
# yield使函数中断,并保存中断的状态,中断后代码可以继续往下执行,过一段时间还可以重新调用这个函数
# def test():
# print('开始了...')
# yield 123 # 返回一个值'a', 暂停函数
# yield 'b'
# yield 'c'
#t = test() # t是生成器对象
# print(t) # <generator object test at 0x000002A492327DC8>
#print(next(t)) #结果为:123
#print(next(t)) #结果为:b
# print(next(t)) #结果为:c
# print(next(t)) #取完元素后,再去取 引发StopIteration异常
#for i in t:
# print(i)
#结果为:123
# b
# c
#return和yield
# 如果生成器函数中有return,return返回的值是StopIteration异常的说明
# def funa():
# yield 123
# return '这是return'
#
# a = funa()
# print(next(a)) #结果为:123
# print(next(a)) #结果为:StopIteration: 这是return
#用生成器打印一到十的数
# def Num(n):
# i=0
# while i<n:
# i+=1
# yield i
#
# c=Num(10) #获取一个生成器,不会调用Num函数
# print(next(c)) #结果为:1 #当调用next方法,获取数据时,才会去调用
# print(next(c)) #结果为:2 在执行next方法,会从上一次yield出来的位置继续执行代码
#使用生成器生成斐波那契数列
# def Scq(y):
# n=n1=1
# x=0
# while x<y:
# x+=1
# yield n
# n,n1=n1,n+n1
#
# b=Scq(10)
# for i in b:
# print(i) #结果为: 1 1 2 3 5 8 13 21 34 55
浙公网安备 33010602011771号