什么叫可迭代对象?
不专业:可以直接作用于 for 循环的对象,统称为可迭代对象:Iterable
稍微专业:通过 Python 内置方法 isinstance(obj, Iterable) 进行判断, 若返回为True则是,反之则不是;
专业解释:该对象含有 __iter__ 方法则称为可迭代对象;
from collections import Iterable, Iteratorclass Classmate(object):def __init__(self):self.name = list()def add(self, name):self.name.append(name)if __name__ == '__main__':c = Classmate()c.add("张三")c.add("李四")c.add("王五")print("c 是否是可迭代对象:", isinstance(c, Iterable))
# 测试结果如下:
# 实例 c 中不含有 __iter__ 方法时,判断显示为 False,即不可迭代对象c 是否是可迭代对象:False
# 当给类 Classmate 加上 __iter__方法时
from collections import Iterable, Iteratorclass Classmate(object):def __init__(self):self.name = list()def add(self, name):self.name.append(name)def __iter__(self):passif __name__ == '__main__':c = Classmate()c.add("张三")c.add("李四")c.add("王五")# 当注释掉类中的 __iter__ ,这里判断会变为 Falseprint("c 是否是可迭代对象:", isinstance(c, Iterable))
# 测试结果如下:
# 实例 c 中不含有 __iter__ 方法时,判断显示为不可迭代对象c 是否是可迭代对象:True
什么叫迭代器?
不专业1:可以被next()函数调用并不断返回下一个值的对象称为迭代器;
不专业2:通过 iter() 函数作用于可迭代对象之后生成的对象称为迭代器;
稍微专业:通过 Python 内置方法 isinstance(obj, Iterator) 进行判断, 若返回为True则是,反之则不是;
专业解释:通过 iter() 函数作用于可迭代对象之后生成的对象,并且该对象含有 __iter__ 和 __next__ 方法;
from collections import Iterable, Iteratorclass Classmate(object):def __init__(self):self.name = list()def add(self, name):self.name.append(name)def __iter__(self):# passreturn ClassIterator()class ClassIterator(object):def __iter__(self):passdef __next__(self):passif __name__ == '__main__':c = Classmate()c.add("张三")c.add("李四")c.add("王五")# 当注释掉类中的 __iter__ ,这里判断会变为 Falseprint("c 是否是可迭代对象:", isinstance(c, Iterable))print("c 是否是迭代器:", isinstance(c, Iterator))d = iter(c)print("d 是否是迭代器:", isinstance(d, Iterator))
# 测试结果如下:
c 是否是可迭代对象:Truec 是否是迭代器:False# 当注释掉 类 ClassIterator 中的任意一个方法,该返回值为 False 或报错d 是否是迭代器:True
那么问题来了,什么时候可以用 for 循环去从可迭代对象或者迭代器中进行取值呢?
先弄清楚,不论是 for 循环是从可迭代对象还是迭代器中取值,都是调用的该对象的 __next__ 方法返回的值,那问题来了,可迭代对象中比如上述代码中的类 Classmate 没有 __next__ 方法就不能取值了?这里答案是否定的,因为类 Classmate 中还有 __iter__ 方法, 调用该方法若返回的对象中有 __next__ 方法,仍旧可以取该方法的返回值;
class Classmate(object):def __init__(self):self.name = list()def add(self, name):self.name.append(name)def __iter__(self):# passreturn ClassIterator()class ClassIterator(object):def __iter__(self):passdef __next__(self):return 111if __name__ == '__main__':c = Classmate()c.add("张三")c.add("李四")c.add("王五")for i in c:print(i)
# 测试结果如下:
控制台会不断打印类 ClassIterator 中的 __next__ 方法的输出 111,这个结果肯定不是我们希望的,我们希望打印我们添加的名称;
略
于是我们继续改造代码如下:
class Classmate(object):def __init__(self):self.name = list()def add(self, name):self.name.append(name)def __iter__(self):# passreturn ClassIterator(self)class ClassIterator(object):def __init__(self, obj):self.obj = objself.num = 0def __iter__(self):passdef __next__(self):res = self.obj.name[self.num]self.num += 1return resif __name__ == '__main__':c = Classmate()c.add("张三")c.add("李四")c.add("王五")for i in c:print(i)
# 测试结果如下:
Traceback (most recent call last):张三File "/Users/wawa/Desktop/code/03协程/迭代器.py", line 46, in <module>李四for i in c:王五File "/Users/wawa/Desktop/code/03协程/迭代器.py", line 32, in __next__res = self.obj.name[self.num]IndexError: list index out of range
继续优化:
class Classmate(object):def __init__(self):self.name = list()def add(self, name):self.name.append(name)def __iter__(self):# passreturn ClassIterator(self)class ClassIterator(object):def __init__(self, obj):self.obj = objself.num = 0def __iter__(self):passdef __next__(self):if self.num < len(self.obj.name):res = self.obj.name[self.num]self.num += 1return reselse:raise StopIterationif __name__ == '__main__':c = Classmate()c.add("张三")c.add("李四")c.add("王五")for i in c:print(i)
# 测试结果如下:
张三李四王五
到这里了好像都实现了,那么问题又来了,可以把上面的两个类用一个类实现吗?
真的是一个好问题~其实这里也是手写迭代器实现 for 循环的逻辑,继续优化代码如下:
class Classmate(object):def __init__(self):self.name = list()self.num = 0def add(self, name):self.name.append(name)def __iter__(self):# pass# return ClassIterator(self)return selfdef __next__(self):if self.num < len(self.name):res = self.name[self.num]self.num += 1return reselse:raise StopIterationif __name__ == '__main__':c = Classmate()c.add("张三")c.add("李四")c.add("王五")for i in c:print(i)
# 测试结果如下:
张三李四王五
慧测三大经典课程体系之性能测试——
课程特点:时间长,费用低,干货多

————————————————
版权声明:本文为CSDN博主「SZ_ChenBolin」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_39386145/article/details/113619581

