迭代器的定义:
1. 当类中定义了__iter__和__next__两个方法;
2. __iter__方法需要返回对象本身,即:self;
3. __next__方法,返回下一个数据,如果没有数据了,则需要抛出一个StopIteration的异常。
# 创建迭代器类
class IT(object):
def __init__(self):
self.counter = 0
def __iter__(self):
return self
def __next__(self):
self.counter += 1
if self.counter == 3:
raise StopIteration()
return self.counter
# 根据类实例化创建一个迭代器对象:
obj1 = IT()
v1 = obj1.__next__()
print(v1)
v2 = next(obj1) # 等价于 v2 = obj1.__next__();next()是python的内置函数,可帮我们自动去执行.__next__()函数python
print(v2)
v3 = next(obj1)
print(v3)
1
2
---------------------------------------------------------------------------
StopIteration Traceback (most recent call last)
~\AppData\Local\Temp\ipykernel_12184\3855014687.py in <module>
22 print(v2)
23
---> 24 v3 = next(obj1)
25 print(v3)
26
~\AppData\Local\Temp\ipykernel_12184\3855014687.py in __next__(self)
10 self.counter += 1
11 if self.counter == 3:
---> 12 raise StopIteration()
13 return self.counter
14
StopIteration:
obj2 = IT()
for item in obj2:
print(item)
1
2
解析:
- IT 类有__iter__和__next__函数,且__iter__返回self, __next__规定了没有数据,就抛出StopInteration异常,所以IT类是一个迭代器类;
- obj1是迭代器类实例化的对象,所以obj1是迭代器对象;
- 迭代器对象可通过next函数取值,如果取值结束则自动抛出StopInteration。
- 迭代器对象可通过for进行循环;for循环的内部机制是:先执行迭代器对象的__iter__方法,然后将返回值(也就是迭代器对象本身obj2)获取到,然后不断执行next,将返回的结果赋值给item,(有异常StopInteration 则终止循环)
- 迭代:一步一步向前进,就比如开发一个软件的迭代周期一样。
生成器
定义:有yied的函数就叫生成器
## 创建生成器函数
def fun():
yield 1
yield 2
# 创建生成器对象(内部是根据生成器类generator创建的对象),生成器类的内部也声明了:__iter__、__next__方法
obj3 = fun()
v1 = next(obj3)
print(v1)
v2 = next(obj3)
print(v2)
v3 = next(obj3)
print(v3)
1
2
---------------------------------------------------------------------------
StopIteration Traceback (most recent call last)
~\AppData\Local\Temp\ipykernel_12184\1829462556.py in <module>
12 print(v2)
13
---> 14 v3 = next(obj3)
15 print(v3)
StopIteration:
obj4 = fun()
for item in obj4:
print(item)
1
2
解析:
如果按照迭代器的规定来看,其实生成器也是一种特殊的迭代器(生成器也是一种特殊的迭代器)
可迭代对象
如果一个类中有__iter__方法且返回一个迭代器对象:则我们称这个类创建的对象为可迭代对象
class Foo():
def __iter__(self):
return 迭代器对象(生成器对象)
obj = Foo() # 可迭代对象
# 可迭代对象是可以使用for进行循环,在循环内部:先执行__iter__方法,获取其迭代器对象,然后再在内部执行这个迭代器对象的next功能,逐步取值。
## 迭代器类
class IT():
def __init__(self):
self.counter = 0
def __iter__(self):
return self
def __next__(self):
self.counter += 1
if self.counter == 3:
raise StopIteration()
return self.counter
class Foo():
def __iter__(self):
return IT()
obj = Foo() # 可迭代对象
for item in obj: # 循环可迭代对象时,内部先执行obj.__iter__并获取迭代器对象;然后不断的执行迭代器对象的next方法
print(item)
1
2
## range 示例
v1 = range(10)
dir(v1) # 有__iter__方法,所以是一个可迭代对象
['__bool__',
'__class__',
'__contains__',
'__delattr__',
'__dir__',
'__doc__',
'__eq__',
'__format__',
'__ge__',
'__getattribute__',
'__getitem__',
'__gt__',
'__hash__',
'__init__',
'__init_subclass__',
'__iter__',
'__le__',
'__len__',
'__lt__',
'__ne__',
'__new__',
'__reduce__',
'__reduce_ex__',
'__repr__',
'__reversed__',
'__setattr__',
'__sizeof__',
'__str__',
'__subclasshook__',
'count',
'index',
'start',
'step',
'stop']
v2 = v1.__iter__()
dir(v2) # v2 有__iter__和__next__方法,所以是迭代器对象
['__class__',
'__delattr__',
'__dir__',
'__doc__',
'__eq__',
'__format__',
'__ge__',
'__getattribute__',
'__gt__',
'__hash__',
'__init__',
'__init_subclass__',
'__iter__',
'__le__',
'__length_hint__',
'__lt__',
'__ne__',
'__new__',
'__next__',
'__reduce__',
'__reduce_ex__',
'__repr__',
'__setattr__',
'__setstate__',
'__sizeof__',
'__str__',
'__subclasshook__']
print(next(v2))
0
print(next(v2))
1
print(next(v2))
2
## 生成自定义的range类
class IterRange():
def __init__(self, num):
self.num = num
self.counter = -1
def __iter__(self):
return self
def __next__(self):
self.counter += 1
if self.counter == self.num:
raise StopIteration()
return self.counter
class Xrange:
def __init__(self,num):
self.max_num = num
def __iter__(self):
return IterRange(self.max_num)
obj = Xrange(5)
for item in obj: ## 执行for循环时:先执行__iter__方法,返回一个IterRange对象,同时还进行参数传递,然后不断执行__next__方法取值
print(item)
0
1
2
3
4
## 基于生成器实现range功能
class Xrange:
def __init__(self, num):
self.max_num = num
def __iter__(self):
counter = 0
while counter < self.max_num:
yield counter
counter += 1
obj = Xrange(6)
for item in obj:
print(item)
0
1
2
3
4
5
# 常见的数据类型:列表、元组、字典
v11 = list([11,22,33,44])
dir(v11) # 包含__iter__方法,所以是可迭代对象
['__add__',
'__class__',
'__contains__',
'__delattr__',
'__delitem__',
'__dir__',
'__doc__',
'__eq__',
'__format__',
'__ge__',
'__getattribute__',
'__getitem__',
'__gt__',
'__hash__',
'__iadd__',
'__imul__',
'__init__',
'__init_subclass__',
'__iter__',
'__le__',
'__len__',
'__lt__',
'__mul__',
'__ne__',
'__new__',
'__reduce__',
'__reduce_ex__',
'__repr__',
'__reversed__',
'__rmul__',
'__setattr__',
'__setitem__',
'__sizeof__',
'__str__',
'__subclasshook__',
'append',
'clear',
'copy',
'count',
'extend',
'index',
'insert',
'pop',
'remove',
'reverse',
'sort']
# v12 = v11.__iter__()
v12 = iter(v12)
dir(v12) # 包含__iter__和__next__方法,所以是迭代器对象,可通过next取值
['__class__',
'__delattr__',
'__dir__',
'__doc__',
'__eq__',
'__format__',
'__ge__',
'__getattribute__',
'__gt__',
'__hash__',
'__init__',
'__init_subclass__',
'__iter__',
'__le__',
'__length_hint__',
'__lt__',
'__ne__',
'__new__',
'__next__',
'__reduce__',
'__reduce_ex__',
'__repr__',
'__setattr__',
'__setstate__',
'__sizeof__',
'__str__',
'__subclasshook__']
# 迭代器对象和可迭代对象的判断
from collections.abc import Iterator, Iterable
v1= [44,55,66]
print(isinstance(v1, Iterator))
print(isinstance(v1, Iterable))
False
True
from collections.abc import Iterator, Iterable
va= [44,55,66]
vb = iter(va)
print(isinstance(vb,Iterator))
print(isinstance(vb,Iterable))
True
True
本文介绍了Python中的迭代器和生成器。迭代器通过实现`__iter__`和`__next__`方法来定义,当没有数据时抛出`StopIteration`异常。通过`next()`函数或`for`循环可以获取迭代器的值。生成器是一种特殊的迭代器,由包含`yield`的函数定义。可迭代对象是指类中有`__iter__`方法并返回一个迭代器的对象。
1959

被折叠的 条评论
为什么被折叠?



