python之(__next__和__iter__实现迭代器协议)

_ iter_()、_ next_()是类的两个内置函数,可以通过定义他们两个实现迭代器协议,产生的实例就可以变成一个迭代器
未定义__iter__()方法会导致无法执行iter()函数

class Foo:

    def __init__(self, n):
        self.n = n


f1 = Foo(10)
for i in f1:
    print(i)
# for函数的本质是调用iter(f1)或者f1.__iter__()方法,将f1变为一个迭代器,但是此处的类未定义__iter__()方法,所以会报
# 'Foo' object is not iterable的错

_ iter_()方法的返回值需要实现可迭代

class Foo:
    def __init__(self, n):
        self.n = n

    def __iter__(self):
        pass


f1 = Foo(10)
for i in f1:
    print(i)
# 此处的类的__iter__()方法没有定义返回值,所以会报iter() returned non-iterator of type 'NoneType'的错

两个方法实现迭代器协议

class Foo:
    def __init__(self, n):
        self.n = n

    def __iter__(self):
        return self

    def __next__(self):
        self.n += 1
        return self.n


f1 = Foo(10)
print(f1.__next__())
for i in f1:
    print(i)
# 每一次的f1.__next__()的结果传给i,f1调用f1.__iter__()变为一个可迭代对象

但是现在没有定义for循环的终止
通过升起StopIteration的异常来终止循环

class Foo:
    def __init__(self, n):
        self.n = n

    def __iter__(self):
        return self

    def __next__(self):
        if self.n < 13:
            self.n += 1
            return self.n
        else:
            raise StopIteration


f1 = Foo(10)
for i in f1:
    print(i)
# for函数会帮忙捕捉异常并终止循环不会报错。如果采用f1.__next__()方法获得下一个值则在最后一个值位置会报错

一个例子:
通过迭代器协议实现的斐波那切数列

class Fib:
    def __init__(self, start1, start2):
        self.start1 = start1
        self.start2 = start2

    def __iter__(self):
        return self

    def __next__(self):
        self.start1, self.start2 = self.start2, self.start1 + self.start2
        return self.start2


f1 = Fib(1, 2)
print(f1.__next__())
print(f1.__next__())
print(f1.__next__())
print(f1.__next__())
print(f1.__next__())


#_*_coding:utf-8_*_
__author__ = 'Linhaifeng'
class Foo:
    def __init__(self,x):
        self.x=x

    def __iter__(self):
        return self

    def __next__(self):
        n=self.x
        self.x+=1
        return self.x

f=Foo(3)
for i in f:
    print(i)
class Foo:
    def __init__(self,start,stop):
        self.num=start
        self.stop=stop
    def __iter__(self):
        return self
    def __next__(self):
        if self.num >= self.stop:
            raise StopIteration
        n=self.num
        self.num+=1
        return n

f=Foo(1,5)
from collections import Iterable,Iterator
print(isinstance(f,Iterator))

for i in Foo(1,5):
    print(i)

练习:简单模拟range,加上步长

class Range:
    def __init__(self,n,stop,step):
        self.n=n
        self.stop=stop
        self.step=step

    def __next__(self):
        if self.n >= self.stop:
            raise StopIteration
        x=self.n
        self.n+=self.step
        return x

    def __iter__(self):
        return self

for i in Range(1,7,3): #
    print(i)

斐波那契数列

class Fib:
    def __init__(self):
        self._a=0
        self._b=1

    def __iter__(self):
        return self

    def __next__(self):
        self._a,self._b=self._b,self._a + self._b
        return self._a

f1=Fib()

print(f1.__next__())
print(next(f1))
print(next(f1))

for i in f1:
    if i > 100:
        break
    print('%s ' %i,end='')
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值