前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Python __iter__ 深入理解

Python __iter__ 深入理解

作者头像
狼啸风云
修改2022-09-02 19:46:16
5580
修改2022-09-02 19:46:16
举报
文章被收录于专栏:计算机视觉理论及其实现

先看一个例子:

代码语言:javascript
复制
class Fib:
    def __init__(self, max):
        self.max = max
    def __iter__(self):
        print('__iter__ called')
        self.a = 0
        self.b = 1
        return self
    def __next__(self):
        print('__next__ called')
        fib = self.a
        if fib > self.max:
            raise StopIteration
        self.a, self.b = self.b, self.a + self.b
        return fib

for i in Fib(3):
    print(i)
# 输出
__iter__ called
__next__ called
0
__next__ called
1
__next__ called
1
__next__ called
2
__next__ called

通过这个斐波那契数列生成器来理解 __iter__。 定义 __iter__ 表示这个类是一个迭代器(iterator)。它只在迭代开始的时候运行一次。返回的是对象本身。这里还给顺手给对象添加了 a 和 b 两个属性。接下来就是循环调用 __next__ 直到遇到 raise StopIteration 为止。调用的过程就是模拟斐波那契数列的过程。

1 1 2 3 5 7 11 18 ... 可以看出,self.a 的值就是数列的值。我们只需要每次迭代把这个值通过 fib 这个变量输出即可。当 self.a = 3 的时候,赋值给 fib,fib > self.max 为假即退出迭代。窍门在于:让数列自己不断迭代,用一个中间的变量 fib 输出。

在迭代器中,__iter__ 和 __next__ 是必须的,而 __init__ 不是。

代码语言:javascript
复制
class Fib:
    def __iter__(self):
        print('__iter__ called')
        self.a = 0
        self.b = 1
        self.max = 3
        return self
    def __next__(self):
        print('__next__ called')
        fib = self.a
        if fib > self.max:
            raise StopIteration
        self.a, self.b = self.b, self.a + self.b
        return fib

以上代码的输出结果和第一段代码是一致的。由于 __iter__ 只允许一次,可以用于赋值给属性。但是,这样的 Fib 类就不能通过传入参数构造了。self.max 被内置了。

为了加深理解,再来一个例子。给定首项 a1, 步长 d,返回末项最接近 n 的一个等差数列。

代码语言:javascript
复制
# 等差数列公式 an = a1 + (n-1) * d
class Acu():
    def __init__(self, a1, d, n):
        self.a1 = a1
        self.d = d
        self.n = n
    def __iter__(self):
        return self
    def __next__(self):
        an = self.a1
        if an > self.n:
            raise StopIteration
        else:
            self.a1 += self.d 
            return an

for i in Acu(1, 2, 15):
    print(i)

完全是一样的道理,首先用 iter 表明这个对象是迭代器,然后调用 next,首先把首项 a1 赋值给 an并输出。在输出前,a1 增加一个步长。这样 an 的值不变,而下一次通过 a1 赋值的时候就变了。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021/01/10 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档