魔法函數__iter__()和__next__()

兩個概念Iterable和Iterator

  • Iterable: 有迭代能力的對象 (如:list, dict, set, tuple,str)
  • Iterator: 迭代器

通過iter()函數可以將有迭代能力的對象轉化成迭代器

可以通過collections類判斷一個對象是Iterable還是Iterator

from collections import Iterable, Iterator

# 常見的Iterable: list, dict
a = [1, 2, 4, 5]

isinstance(a, Iterable)   # True
isinstance(a, Iterator)   # Fasle

b = iter(a)

isinstance(b, Iterable)   # True
isinstance(b, Iterator)   # True

迭代器是一個可以記住遍歷位置的對象。(只能向前迭代不能後退)

迭代器是一個可以被next()函數調用並不斷返回下一個值的對象

有迭代能力的對象從集合的第一個元素開始訪問,真到所有元素訪問完畢

# 兩者都可用for語句迭代元素
for i in a:
    print(i)

for i in b:
    print(i)
# Iterator對象可用next()函數迭代元素(一直向後)
next(b)    # 1
next(b)    # 2

# 到最後無元素時,拋出StopIteration異常

__iter__和__next__

iter()函數主要映射類中__iter__函數

next()函數主要映射類中__next__函數

class A(object):
    def __iter__(self):
        print("返回一個類B對象")
        return B()


class B(object):
    def __next__(self):
        print(" you got me!!!!!!")

obj_a = A()  # 類A實例
obj_b = B()  # 類B實例
iter(obj)  # 返回一個類B對象
next(iter(obj))  # 返回一個類B對象    you got me!!!!!! 

一個類實現了__iter__, 我們認爲它有迭代能力,稱其爲Iterable.

一個類同時實現了__iter__和__next__,稱其爲Iterator.

modify(obj_a)  # 當前對象爲Iterable
modify(obj_b)    # 什麼都不是

 帶有迭代器的類

class MyRange(object):
    def __init__(self, end):
        self.start = 0
        self.end = end

    def __iter__(self):
        return self

    def __next__(self):
        if self.start < self.end:
            ret = self.start
            self.start += 1
            return ret
        else:
            raise StopIteration


m = MyRange(5)
modify(m)          # Iterable, Iterator

# 利用for語句迭代元素,會捕獲StopIteration異常並自動結束for
for i in m:
    print(i)
# 利用next()函數迭代元素
print(next(a))
print(next(a))
print(next(a))
print(next(a))
print(next(a))
print(next(a)) # 其實到這裏已經完成了,我們在運行一次查看異常

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章