首頁 >後端開發 >Python教學 >python yield和yield from用法總結詳解

python yield和yield from用法總結詳解

coldplay.xixi
coldplay.xixi轉載
2020-08-19 17:08:303513瀏覽

python yield和yield from用法總結詳解

python yield和yield from用法總結

yield 作用:

#註: generator的next()方法在python 2中為next(),但在python 3中為__next__() 【next的前後各是兩個底線】

  把一個函數變成一個generator,帶有yield的函數不再是一個普通函數。即:一個帶有yield 的函數就是一個generator,它和普通函數不同,生成一個generator 看起來像函數調用,但不會執行任何函數代碼,直到對其調用next()(在for 循環中會自動調用next())才開始執行。雖然執行流程仍按函數的流程執行,但每執行到一個 yield 語句就會中斷,並傳回一個迭代值,下次執行時從 yield 的下一個語句繼續執行。看起來好像一個函數在正常執行的過程中被 yield 中斷了數次,每次中斷都會透過 yield 傳回目前的迭代值。

yield 的好處是顯而易見的,把一個函數改寫為一個generator 就獲得了迭代能力,比起用類別的實例保存狀態來計算下一個next() 的值,不僅程式碼簡潔,而且執行流程異常清晰。

用print實作列印斐波拉切數列-基礎版

#!/usr/bin/env python
# -*- coding: utf-8 -*-def fab(max):
    n , a, b = 0, 0 , 1
    while n < max:
        print(b)
        a, b = b, a + b
        n = n + 1if __name__ == &#39;__main__&#39;:
    fab(6)  # 1 1 2 3 5 8

用yield實作列印斐波拉切數列-升級版

#!/usr/bin/env python
# -*- coding: utf-8 -*-def fab(max):
    n , a, b = 0, 0 , 1
    while n < max:
        yield b
        a, b = b, a + b
        n = n + 1if __name__ == &#39;__main__&#39;:
    for n in fab(6): # 1 1 2 3 5 8
        print(n)

如何判斷一個函數是否是一個特殊的generator函數

#!/usr/bin/env python
# -*- coding: utf-8 -*-from inspect import isgeneratorfunction

def fab(max):
    n , a, b = 0, 0 , 1
    while n < max:
        yield b
        a, b = b, a + b
        n = n + 1if __name__ == &#39;__main__&#39;:
    f1 = fab(3)
    # True fab是一个generator function
    print(isgeneratorfunction(fab))

    # False fab(3)不是一个generator function
    # 而fab(3)是调用fab返回的一个generator    print(isgeneratorfunction(fab(3)))

用yield實作大檔案讀取

#!/usr/bin/env python
# -*- coding: utf-8 -*-def read_file(fpath):
    BLOCK_SIZE = 100
    with open(fpath, "rb") as f:
        while True:
            block = f.read(BLOCK_SIZE)
            if block:
                yield block            else:
                returnif __name__ == &#39;__main__&#39;:
    fpath = "/home/exercise-python3.7.1/vote/mysite/mysite/polls/test.txt"
    read_gen = read_file(fpath)

    print(read_gen.__next__())
    print(read_gen.__next__())
    print(read_gen.__next__())
    print(read_gen.__next__())

    # for循环会自动调用generatr的__next__()方法,故输出效果同如上的4个print  【内容较短,4个print就将test.txt中的内容输出完了】    for data in read_gen:
        print(data)

yield 和yield from 用法比較

使用yield拼接可迭代物件

#!/usr/bin/env python
# -*- coding: utf-8 -*-if __name__ == &#39;__main__&#39;:
    astr = "ABC"
    alist = [1, 2, 3]
    adict = {"name": "wangbm", "age": 18}
    # generate
    agen = (i for i in range(4, 8))

    def gen(*args, **kw):
        for item in args:
            for i in item:
                yield i

    new_list = gen(astr, alist, adict, agen)
    print(list(new_list))
    # [&#39;A&#39;, &#39;B&#39;, &#39;C&#39;, 1, 2, 3, &#39;name&#39;, &#39;age&#39;, 4, 5, 6, 7]

使用yield from拼接可迭代對象

#!/usr/bin/env python
# -*- coding: utf-8 -*-if __name__ == &#39;__main__&#39;:
    astr = "ABC"
    alist = [1, 2, 3]
    adict = {"name": "wangbm", "age": 18}
    # generate
    agen = (i for i in range(4, 8))

    def gen(*args, **kw):
        for item in args:
            yield from item

    new_list = gen(astr, alist, adict, agen)
    print(list(new_list))
    # [&#39;A&#39;, &#39;B&#39;, &#39;C&#39;, 1, 2, 3, &#39;name&#39;, &#39;age&#39;, 4, 5, 6, 7]

結論:
  由上面兩種方式對比,可以看出,yield from後面加上可迭代對象,他可以把可迭代對象裡的每個元素一個一個的yield出來,對比yield來說程式碼更簡潔,結構更清晰。

相關學習推薦:python影片教學

#

以上是python yield和yield from用法總結詳解的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:learnku.com。如有侵權,請聯絡admin@php.cn刪除