python之for…in…循环的本质

  • Post author:
  • Post category:python



目录


序言:


for 循环本质这里通过三个例子来进行叙述:


例一、p是自定义的迭代器对象


例二、p是自定义的可迭代对象


例三、p是现成的可迭代对象或迭代器对象



序言:

一个对象有实现两个发法:__iter__()、__next__(),则称之为迭代器对象;

一个对象有实现发法__iter__(),则称之为可迭代对象。

内置函数 iter() 只会调用对象的__iter__()方法;

内置函数 next() 只会调用对象的__next__()方法。

Iterable 和 Iterator 都有 __iter__() 方法,异同之处在于 iterable 的__iter__()方法返回一个迭代器,iterator 的__iter__()方法返回本身(也是一个迭代器)。


for 循环本质这里通过三个例子来进行叙述:

例一、p是自定义的迭代器对象

class Person:
    def __init__(self):
        self.age = 1

    def __iter__(self):
        print('----------iter')
        return self

    def __next__(self):
        print('----------next')
        self.age += 1
        if self.age > 6:
            raise StopIteration('大于6了')
        return self.age
p = Person()
# 通过collections模块判断迭代器、可迭代对象
from collections.abc import Iterable, Iterator
print(isinstance(p, Iterator))
print(isinstance(p, Iterable))
for i in p:
    print(i)

此代码执行逻辑:python解释器会先判断 p 是否为可迭代对象,即判断 p 是否存在__iter__()方法,如果存在,则解释器会自动调用 iter() 函数操作 p 即 iter(p),本质上是间接调用 p 的__iter__()方法,返回 self 即迭代器对象本身,并且随后解释器会自动地不断调用 next() 函数操作 self 即 next(self),本质上是间接地不断调用 p 的__next__()方法,返回下一个数据并赋值给 i,同时打印输出。

例二、p是自定义的可迭代对象

class Person:
    def __iter__(self):
        print('----------iter')
        return iter([1,2,3])
p = Person()
from collections.abc import Iterable, Iterator
print(isinstance(p, Iterator))
print(isinstance(p, Iterable))
for i in p:
    print(i)


1、

此代码执行逻辑:python解释器会先判断 p 是否为可迭代对象,即判断 p 是否存在__iter__()方法,如果存在,则解释器会自动调用 iter() 函数操作 p 即 iter(p),本质上是间接调用 p 的__iter__()方法,返回 iter([1,2,3]) 即一个迭代器对象,并且随后解释器会自动地不断调用 next() 函数操作 iter([1,2,3]) 即 next(iter([1,2,3])),本质上是间接地不断调用 iter([1,2,3]) 的__next__()方法,返回下一个数据并赋值给 i,同时打印输出;否则,直接抛出 TypeError 错误。【小记:一个对象实现了__iter__()方法就可称之为可迭代对象,不需要考虑该方法返回的是不是迭代器,但是当 for 循环遍历可迭代对象时,该方法必须返回一个迭代器,否则报错。例一也是如此】


2、

此时再考虑一下,如果实例化出 p 对象后,再调用 iter() 函数操作 p 即 iter(p),会怎么样?其实解释器在读取完 lp = iter(p) 后,会间接调用 p 的__iter__()方法,返回 self 即 p 即一个迭代器对象,所以 print(lp is p) 结果为True。

class Person:
    def __init__(self):
        self.age = 1

    def __iter__(self):
        print('----------iter')
        return self

    def __next__(self):
        print('----------next')
        self.age += 1
        if self.age > 6:
            raise StopIteration('大于6了')
        return self.age
p = Person()
lp = iter(p)
print(lp is p)

例三、p是现成的迭代器对象或可迭代对象

p = iter([1,2,3])
for i in p:
    print(i)

p = [1,2,3]
for i in p:
    print(i)

代码执行逻辑:对应着例一、例二琢磨。



版权声明:本文为world_in_world原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。