python 运算符重载迭代器对象__iter__,__next__

#python中所有的迭代环境都会先尝试__iter__方法,在尝试__getitem__,只有在对象不支持迭代协议时,才会尝试索引
#迭代环境是通过调用内置函数iter去尝试寻找__iter__方法来实现的,而这种方法应该返回一个迭代器,如果已经提供了,python会重复调用这个迭代器对象的next方法,直到发生stopIteration异常,如果没有找到__iter__方法,python会改用__getitem__机制

class Squares:
    def __init__(self, start, stop):
        self.value=start-1
        self.stop=stop
    def __iter__(self):
        return self
    def __next__(self):
        if self.value==self.stop:
            raise StopIteration
        self.value+=1
        return self.value**2
    
s=Squares(1,1)
print(s)    #<__main__.Squares object at 0x0000023291823F60>
print(iter(s)==s)    #True   s是个迭代器对象
for i in s:
    print(i)
    
#print(next(s))   #builtins.StopIteration:
#print(s[1])    #迭代器没有重载索引表达式 builtins.TypeError: 'Squares' object does not support indexing

#__iter__只循环一次,而不是循环多次,每次新的循环都要创建一个新的迭代器
x=Squares(1,5)
print([n for n in x])    #[1, 4, 9, 16, 25]
print([n for n in x]) #[]
print([n for n in Squares(1,3)])    #[1, 4, 9]
print(list(Squares(1,3)))    #[1, 4, 9]

#要达到多个迭代器的效果,__iter__只需替迭代器定义新的状态对象,而不是返回self
class SkipIterator:
    def __init__(self, wrapped):
        self.wrapped=wrapped
        self.offset=0
    def __next__(self):
        if self.offset>=len(self.wrapped):
            raise StopIteration
        else:
            item=self.wrapped[self.offset]
            self.offset+=2
            return item
        
class SkipObject:
    def __init__(self, wrapped):
        self.wrapped=wrapped
    def __iter__(self):
        return SkipIterator(self.wrapped)
    
a='abcdef'
s=SkipObject(a)
print(s)    #<__main__.SkipObject object at 0x000001DEB47D4400>
#print(next(s))    #SkipObject没有定义__next__,builtins.TypeError: 'SkipObject' object is not an iterator
i=iter(s)    #s是可迭代对象,返回一个迭代器i
print(i)    #<__main__.SkipIterator object at 0x000001F2049EA1D0>
print(next(i), next(i), next(i))   #a c e
#print([x for x in i])    #i不支持迭代,builtins.TypeError: 'SkipIterator' object is not iterable
for x in s:    #s不是一个迭代器,只是可以迭代的对象,因此每个循环都自己在字符串中的位置
    for y in s:
        print(x+y, end=', ')    #aa, ac, ae, ca, cc, ce, ea, ec, ee,
print()
for x in 'ace':
    for y in 'ace':
        print(x+y, end=', ')    #aa, ac, ae, ca, cc, ce, ea, ec, ee,
#这两种方式可以达到相同的结果,但是第二种是把列表整个存储在内存中,而迭代器是一次产生一个值,这样使得大型列表节省了实际的空间
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值