python编程之迭代器

什么是可迭代对象

可迭代对象:在Python中,可迭代对象是指可以被迭代的对象,即可以使用 for 循环遍历其元素的对象。

1
2
3
4
5
6
7
8
from collections.abc import Iterable

nums = [1, 2, 3]

for num in nums:
print(num)

print(isinstance(nums, Iterable)) # True

在上述代码中我们创建了一个列表,这个列表中的元素可以被我们的for循环所遍历,那么nums就是一个可迭代对象。最下边我们通过一个python内置方法instance来检查nums是否是Iterable类的实例,打印了True说明nums是Iterable类的一个实例,要是Iterable的子类一定是一个可迭代对象。

instance内置方法

isinstance是python的内置函数,判断一个类的实例是否是指定类的实例,支持继承关系

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class A:
pass


class B(A):
pass


a = A()
b = B()

print(isinstance(a, A)) # True
print(isinstance(b, A)) # True
print(isinstance(a, B)) # False

什么是迭代器对象

迭代器是一种对象,它实现了迭代器协议,即包含 iter() 和 next() 方法。迭代器对象用于在迭代过程中逐个访问元素,每次调用 next() 方法都会返回序列中的下一个元素,直到序列中没有元素可返回,此时会引发 StopIteration 异常。
iter函数是python中的一个内置函数,传递一个可迭代对象将这个对象转为一个迭代器对象

1
2
3
4
5
6
7
8
9
10
11
12
nums = [1, 2, 3]
print(next(nums)) # 这里会报错,因为只有迭代器对象才拥有next方法
"""
在python中iter()和__iter__的作用是一样的,因为__iter__是比较底层的方法,所以推荐使用iter()
下面这段代码将nums从一个可迭代对象转为一个迭代器对象
"""
obj = iter(nums) # 此时obj对象将拥有next方法

print(next(nums)) # 1
print(next(nums)) # 2
print(next(nums)) # 3
print(next(nums)) # 如果元素取完则引发报错:StopIteration

通过instance方法来判断对象是否为迭代器对象

1
2
3
4
5
from collections.abc import Iterator

nums = [1, 2, 3]
print(isinstance(nums, Iterator)) # False,列表对象不是迭代器对象
print(isinstance(iter(nums), Iterator)) # True

自定义类实例化返回迭代器对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class ListNode:
def __init__(self):
self.person_list = list()

# 如果一个类内部定义了__iter__方法,那么创建出来的实例一定是一个可迭代对象
def __iter__(self):
pass

def __next__(self):
pass


list_node = ListNode()
print(isinstance(list_node, Iterable)) # True
print(isinstance(list_node, Iterator)) # True

在上面这段代码中我们自定义了一个类,该类拥有__iter__和__next__方法,那么该类的实例对象就是一个迭代器对象,如果将该类的__next__方法注释,那么该类的实例对象就是一个可迭代对象。可迭代对象不一定是迭代器对象,迭代器对象一定是一个可迭代对象。

__iter__和__next__具体的使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
class ListNode:
def __init__(self):
self.index = 0
self.stu_list = list()

def __iter__(self):
return self

def __next__(self):
if self.index < len(self.stu_list):
item = self.stu_list[self.index]
self.index += 1
return item
else:
print('元素被取完了')
raise StopIteration

def add(self, name):
self.stu_list.append(name)


list_node = ListNode()
list_node.add('安娜')
list_node.add('双双')

for stu in list_node:
print(stu)

在上面这段代码中我们定义了一个ListNode类,该类中声明了__iter__和__next__方法,先实例化了ListNode类对象,随后通过add方法添加了两个学员,那么我们使用for循环直接去遍历ListNode类的实例对象是可以正常将类中列表的内容打印出来,因为for循环实质上是先将调用iter方法将需要遍历的对象转为迭代器对象,然后迭代器对象去执行next方法,从而将元素遍历出来,next方法的作用就是定义如何在一个迭代器对象中获取元素