# Author: Django
# 2020-3-18
# #迭代器
# l = [1,2,3,4]
# # 遍历的方法:
# #索引,循环
# #能被for循环的:字符串,元组,列表,集合,字典,文件,range,enumerate(枚举)
# # 为什么能循环?
# # 答:
# print(dir([])) #告诉列表所拥有的所有方法
# #一般带双下划线的方法叫做双下方法,这些都是C语言写好的,我们可以通过许多方式调用。双侠方法一般不调用
# print([1].__add__([2]))
# print([1] + [2]) #其实这些是解释器调用函数解决问题的过程
# #既让可以看列表的双下方法,那么也可以看其他数据类型的双下方法。
# # 查看各种数据类型的方法
print(dir([]))
print(dir({}))
print(dir(''))
print(dir(range(10)))
#现在要查看这些方法所共同拥有的方法
#这里采用交集来处理
ret = set(dir([]))&set(dir({}))&set(dir(''))&set(dir(range(10)))
print(ret) #iterable
# for i in 123: # 是不可迭代的
# print(i)
print('__iter__'in dir(int)) #无法被for循环,那么就是不可迭代的
print('__iter__'in dir(list))
print('__iter__'in dir(dict))
print('__iter__'in dir(set))
print('__iter__'in dir(tuple))
print('__iter__'in dir(enumerate([])))
print('__iter__'in dir(range(10)))
print('__iter__'in dir(bool))
# 以上结果说明,只要能被for循环的数据类型,就有__iter__方法
print([].__iter__()) #iterator就叫迭代器
# 迭代器:一个列表执行了__iter__之后的返回值就是一个迭代器
# [].__iter__()就得到一个迭代器 而----》__next__通过next就可以从迭代器中一个个取值
# 可迭代协议:只要含有__iter__方法都是可迭代的。
#迭代器协议:内部同时含有__next__和__iter__方法的就是迭代器
from collections import Iterable
from collections import Iterator
print(isinstance([],Iterable))
print(isinstance([],Iterator))
只要是迭代器就一定可迭代
可迭代的._iter-方法就可以得到一个迭代器,迭代器中的next方法可以一个一个的获取值
其实for循环就是在使用迭代器,而学习迭代器就是因为很多时候都是返回的一个迭代器,直接给内存地址
得爱妻的好处,从容器中一个一个取值,会把所有的值都取到
还可以节省内存空间迭代器不会在内存中生成一大块数据,而是随着循环每次生成一个,每次next给我一个值
#想生产两百万个字符串要怎么实现呢?
# def func():
# for i in range(100000):
# i = 'DuoLaAmeng' % i
# return i
#生成器和生成器函数
# def generator():
# print('DuoLaAmeng')
# return 1
# rat = generator()
# print(rat)
#只要含有yield关键字的函数都是生成器,yield必须写在函数里,且yield与return不能同用
def generator1(): #第一步
print(1) #第六步
yield 'a' #第七步 'a'会被当做一个返回值传递给rit,因为generator1调用了
# 生成器函数执行之后会得到一个生成器作为返回值
rit = generator1() #rit拿到的是一个生成器 这是第二步和第三步
print(rit) #第四步
print(rit.__next__()) # 第五步