美文网首页
迭代对象

迭代对象

作者: 代码表演艺术家 | 来源:发表于2020-08-14 16:00 被阅读0次

迭代对象就是可以使用for in 来遍历的对象,常见的list dict string 等都是可迭代的对象,除此之外我们可以定义自己的对象为可迭代对象,这样就可以直接在对象上使用for 循环遍历了

只要类里面含有__iter()__ 和__next()__ 类方法,就可以实现可迭代对象
其中:
__iter()__ 方法来返回一个可迭代对象,一般就是返回self 本身就可以了
__next()__方法用来返回每次迭代的值,一般在可迭代类里需要维护一个控制迭代次数的变量,这个变量在每次调用__next()__方法时都要更新,表示迭代到的位置

class users:
    def __init__(self,user_list):
        self.users=user_list
        self.count=len(user_list)

    def __iter__(self): # 必须要有这个函数,虽然只是返回自己,不然在for语句不认为当前对象可以使用for循环
        return self # 没有这个函数的话,会报错 TypeError: 'users' object is not iterable

    def __next__(self):
        if self.count>0:
            self.count-=1
            return self.users[self.count]
        else:
            raise StopIteration


u1=users(['jack','mike','tom'])

for x in u1:
    print(x)

#输出:
tom
mike
jack

分析一下迭代对象在for 语句里面的执行过程:
语句for x in u1 在开始执行前会获取u1对象的__iter()__方法来获取可迭代对象,这里获得的就是u1本身,然后for 循环内部会不停的调用u1.__next()__来获取值,直到遇到StopIteration异常,其实python内置的函数next也能实现相同的功能,通过多次调用next(u1)每次都会获取不同的返回,

u1=users(['jack','mike','tom'])
print(next(u1))
print(next(u1))
print(next(u1))
print(next(u1))

#输出:
tom
mike
jack
Traceback (most recent call last):
  File "C:/Users/young.yu/Desktop/test.py", line 23, in <module>
    print(next(u1))
  File "C:/Users/young.yu/Desktop/test.py", line 14, in __next__
    raise StopIteration
StopIteration

可以看到第四次调用的时候触发了StopIteration后退出。
为什么这里print(next(u1))每次使用相同的函数,相同的对象,但返回的却不同?因为每次调用next(u1)其实在u1对象内部都会更新属性self.count的值,而迭代对象就是通过这个属性来控制返回的值和迭代次数的。

如果没有维护这么一个属性的话,for 循环会怎么样?

class users:
    def __init__(self,user_list):
        self.users=user_list

    def __iter__(self):
        return self  

    def __next__(self):
        for i in self.users:
            return i


u1=users(['jack','mike','tom'])

for x in u1: # 这里会无限循环输出jack
    print(x)
    
print(next(u1))  # 下面这些调用都会输出一样的jack
print(next(u1))
print(next(u1))
print(next(u1))

上面的代码因为没有在迭代对象里维护一个控制迭代次数的对象,所以每次next(u1)都是完全一样的环境,都输出一样的值

相关文章

网友评论

      本文标题:迭代对象

      本文链接:https://www.haomeiwen.com/subject/tkwgdktx.html