python 3.x python迭代器进阶
迭代器进阶
python中的迭代协议
- 什么是迭代协议???
- 有两个类型:
- 可迭代对象(Iterable),实现__iter__().如:list
- 迭代器对象(Iterator),实现__next__()和__iter__(),主要是实现__next__()方法.
- 迭代器是什么???
- 迭代器是访问集合内元素的一种方式,一般用来遍历数据.
- 迭代器和以下标的访问方式是不一样的,迭代器是不能返回的.所以不能使用下标来访问迭代器来获取数据.
- 迭代器提供了一种惰性访问数据的方式,实际上生成器的背后也是迭代器,他可以让我们在访问数据的时候才去计算或者说获取数据这个和我们的list是不一样的
- 以下标来访问数据[index],背后的原理是__getitem__()
- 在python中所有可迭代的类型背后都是实现迭代协议的,所以说可以对可迭代类型进行for循环.
- 这个可迭代协议就是__iter__
- list内部只实现了__iter__()方法,并没有实现__next__(),所以list只是一个可迭代的数据类型而不是迭代器
- Iterable内部实现源码:
-
1 class Iterable(metaclass=ABCMeta): 2 3 __slots__ = () 4 5 @abstractmethod 6 def __iter__(self): 7 while False: 8 yield None 9 10 @classmethod 11 def __subclasshook__(cls, C): 12 if cls is Iterable: 13 return _check_methods(C, "__iter__") 14 return NotImplemented
-
- Iterator内部实现源码:
-
1 class Iterator(Iterable): 2 3 __slots__ = () 4 5 @abstractmethod 6 def __next__(self): 7 'Return the next item from the iterator. When exhausted, raise StopIteration' 8 raise StopIteration 9 10 def __iter__(self): 11 return self 12 13 @classmethod 14 def __subclasshook__(cls, C): 15 if cls is Iterator: 16 return _check_methods(C, '__iter__', '__next__') 17 return NotImplemented
-
示例代码:
1 from collections.abc import Iterable, Iterator 2 3 a_list = [1, 2] 4 5 # True 6 print(isinstance(a_list, Iterable)) 7 # False 8 print(isinstance(a_list, Iterator)) 9 10 """ 11 综上list只是一个可迭代类型Iterable,而不是一个迭代器Iterator 12 """ 13 14 b_list = [1, 2] 15 16 # iter()方法返回一个迭代器对象 17 iter_rator = iter(b_list) 18 19 # True 20 print(isinstance(b_list, Iterable)) 21 # True 22 print(isinstance(iter_rator, Iterator)) 23 # False 24 print(isinstance(b_list, Iterator))
示例代码:
1 """ 2 迭代器和可迭代对象的区别 3 可迭代对象Iterable : 内部实现__iter__()魔法函数,返回迭代器(Iterator) 4 迭代器Iterator : 内部实现__iter__()魔法函数,返回自己self.同时实现__next__()魔法函数. 5 6 list是一个可迭代对象. 7 """ 8 from collections.abc import Iterable, Iterator 9 10 11 class Company(object): 12 def __init__(self, employee_list): 13 self.employee_list = employee_list 14 15 # def __iter__(self): 16 # return iter([1, 2, 3]) 17 18 def __getitem__(self, item): 19 return self.employee_list[item] 20 21 22 if __name__ == "__main__": 23 company = Company(["tom", "jerry", "jack"]) 24 25 # company为什么可以进行for循环??? 26 # company在进行for循环的时候python解释器内部会去调用iter(company),python的内置方法. 27 # 尽管没有在类Company中实现__iter__魔法函数,但是内置方法iter()非常的智能, 28 # iter()会去到Company中去查找是否有__iter__()魔法函数, 29 # 如果有会调用__iter__()方法.输出结果: 1,2,3 30 # 如果没有,iter()会创建默认的迭代器.而这个默认的迭代器通过__getitem__()魔法函数来进行遍历,从0开始遍历,输出结果tom,jerry,jack 31 for item in company: 32 print(item) 33 34 # 输出结果: 35 # tom 36 # jerry 37 # jack
示例代码:
1 """ 2 迭代器和可迭代对象的区别 3 可迭代对象Iterable : 内部实现__iter__()魔法函数,返回迭代器(Iterator) 4 迭代器Iterator : 内部实现__iter__()魔法函数,返回自己self.同时实现__next__()魔法函数. 5 6 list是一个可迭代对象. 7 """ 8 from collections.abc import Iterable, Iterator 9 10 11 class Company(object): 12 def __init__(self, employee_list): 13 self.employee_list = employee_list 14 15 def __iter__(self): 16 return iter([1, 2, 3]) 17 18 def __getitem__(self, item): 19 return self.employee_list[item] 20 21 22 if __name__ == "__main__": 23 company = Company(["tom", "jerry", "jack"]) 24 25 # company为什么可以进行for循环??? 26 # company在进行for循环的时候python解释器内部会去调用iter(company),python的内置方法. 27 # 尽管没有在类Company中实现__iter__魔法函数,但是内置方法iter()非常的智能, 28 # iter()会去到Company中去查找是否有__iter__()魔法函数, 29 # 如果有会调用__iter__()方法.输出结果: 1,2,3 30 # 如果没有,iter()会创建默认的迭代器.而这个默认的迭代器通过__getitem__()魔法函数来进行遍历,从0开始遍历,输出结果tom,jerry,jack 31 for item in company: 32 print(item) 33 34 # 输出结果: 35 # 1 36 # 2 37 # 3
示例代码:
1 """ 2 迭代器和可迭代对象的区别 3 可迭代对象Iterable 4 迭代器Iterator 5 1.迭代器是不支持切片的,不支持切片的好处是说明迭代器只是用来迭代的,迭代的时候在我们需要的时候产生数据. 6 迭代器和list的应用场景是不一样的. 7 2.迭代器的作用: 8 在大数据量的情况下,读取大文件或者遍历大文件,比如这个文件上T的时候,不可能将大数据放到list中(因为占大量的内存), 9 而是用__next__()这种迭代器模式,是从任意位置读数据. 10 11 python中迭代器的设计是经典设计模式的一种.实际上要遍历一种数据类型或者说遍历一种数据结构的时候, 12 要在该可迭代对象(Company)中使用迭代器.然后将可迭代对象(company)中的可迭代对象数据(employee_list), 13 传递给迭代器(MyIterator).通过__iter__()魔法函数返回迭代器(MyIterator).由迭代器(MyIterator)去维护index, 14 不要在可迭代对象(Company)内部来维护index,同时不要在可迭代对象(Company)中调用__next__()魔法函数和next()内置方法. 15 这就是python编写迭代器的规则. 16 """ 17 from collections.abc import Iterable, Iterator 18 19 20 class Company: 21 def __init__(self, employee_list): 22 self.employee_list = employee_list 23 24 def __iter__(self): 25 # 返回迭代器 26 return MyIterator(self.employee_list) 27 28 29 class MyIterator: 30 def __init__(self, employee_list): 31 self.employee_list = employee_list 32 self.__index = 0 33 34 def __iter__(self): 35 return self 36 37 def __next__(self): 38 # 真正返回迭代值的逻辑 39 try: 40 word = self.employee_list[self.__index] 41 except IndexError: 42 raise StopIteration 43 44 self.__index += 1 45 return word 46 47 48 if __name__ == "__main__": 49 company = Company(["tom", "jerry", "jack"]) 50 # my_iterator = MyIterator(["tom", "jerry", "jack"]) 51 my_iter = iter(company) 52 53 # 需要手动处理StopIteration异常,麻烦. 54 # while True: 55 # try: 56 # print(next(my_iterator)) 57 # except StopIteration: 58 # break 59 60 # for语句在内部完成对StopIteration异常的处理,简洁不用手动处理异常. 61 for item in my_iter: 62 print(item)
********
posted on 2019-04-14 08:35 jaydenjune 阅读(39) 评论(0) 收藏 举报
浙公网安备 33010602011771号