Python的迭代器和生成器解析

迭代器

重复取值的工具。必须要与上一次有一定关联

num = 0
while True:
    print(num)
    num+=1

可迭代对象

只要内置有_iter__()方法的就可以称之为可选代对象。
可以转换为迭代器的对象,就称之为可迭代对象

如下都是可迭代对象:

a = [1,2,3]
a.__iter__()

b = (1,2,3)
b.__iter__()

c = {'a':1,"b":2}
c.__iter__()

d = '123'
d.__iter__()

with open('111.yaml','r') as f:
    f.__iter__()

注意 iterator,迭代器对象

c = {'a':1,"b":2}
res = c.__iter__()
"""
只要是迭代器对象都会内置一个__next__方法
调用一次打印一次
"""
print(res.__next__())
print(res.__next__())
print(res.__next__())
"""
迭代器很节省内存资源
当没有可以__next__的时候就会抛出StopIteration异常
"""

for循环原理

总结

迭代器对象: 内置有 next 0方法,并且还内置 iter 0方法的对象

迭代器对象调用 next 0方法,就会得到迭代器的下一个值

迭代器对象调用 iter 0方法,得到迭代器本身(和没调用一样)

结果为True:

c = {'a':1,"b":2}
res = c.__iter__()
print(res.__iter__() is res)

for循环解释:

for i in 可迭代对象.__iter__()
for i in 迭代器对象.__iter__()

例子:

c = {'a':1,"b":2}
for key in c:
    print(key)
	
"""
1、调用对象的__iter__()方法,得到一个迭代器对象
2、调用迭代器的__next__()方法,拿到一个返回值
3、循环执行第二步,知道抛出异常,就捕获异常,并结束循环
"""

不能说可迭代对象是迭代器对象,可以说迭代器对象也是可迭代对象.

文件是一个迭代对象:

with open('111.yaml','r') as f:
    f.__iter__()
	f.__next__()

生成器

yield

def func():
    print("第一次执行") 
    yield 1
    print("第一次执行")
    yield 2
    print("第一次执行")
    yield 3
    print("第一次执行")
    
res = func()
print(res)
"""<generator object func at 0x000001A8142DA7B0>"""

生成器就是迭代器,自定义的迭代器

def func():
    print("第一次执行")
    yield 1
    print("第一次执行")
    yield 2
    print("第一次执行")
    yield 3
    print("第一次执行")

res = func()
print(res.__next__())
print(res.__next__())
print(res.__next__())
print(res.__next__())
"""
第一次执行
1
第一次执行
2
第一次执行
3
第一次执行
StopIteration错误
"""

调用函数则会有一个生成器。当超出yield关键字后,就会抛出Stoplteration错误,跟选代器一致

yield关键字存在这里,调用一次执行一次,不调用的时候就会停在此处,调用的时候使用 next 0方法,执行完print后会将vield后面的值进行返回,yield后面可以不跟任何东西,那么调用的时候返回的就是none。

yield表达式

def func(a= 1):
    print(f"我执行了{a}次")
    a += 1
    while True:
        x = yield
        print(f"我执行了第{a}次,并且{x}")

res = func()
# res.send(10)    # TypeError: can't send non-None value to a just-started generator
res.send(None)  # 相当于next(g),触发函数代码的运行
res.send(10)

拓展

def func():
    print("第一次执行")
    yield 1
    print("第一次执行")
    yield 2
    print("第一次执行")
    yield 3
    print("第一次执行")

res = func()
print(res.__iter__())
print(iter(res))
print(res.__next__())
print(res.__next__())
print(next(res))
print(next(res))

上述二者本质上是一样的,不论调用iter还是next0,执行的时候都会调用到 iter 0或 next 0方法

示例

pytest的fixture机制:

from selenium import webdriver

def func():
    while True:
        driver =  webdriver.Firefox()
        yield driver

driver = func()
res = next(driver)
res.get('https://www.baidu.com')
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值