亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Python中的yield全方位解讀

 更新時(shí)間:2023年08月21日 09:42:46   作者:軟件測(cè)試技術(shù)  
這篇文章主要介紹了Python中的yield全方位解讀,在 Python 中,使用了 yield 的函數(shù)被稱為生成器,跟普通函數(shù)不同的是,生成器是一個(gè)返回迭代器的函數(shù),只能用于迭代操作,更簡(jiǎn)單點(diǎn)理解生成器就是一個(gè)迭代器,需要的朋友可以參考下

Python中的yield

關(guān)于 yield 看了忘,忘了看,零零散散的總是理解不透徹。今天徹底記錄下,帶大家一探 yield 到底是什么?

關(guān)于生成器概念的解釋,摘自菜鳥(niǎo)教程解釋:

在 Python 中,使用了 yield 的函數(shù)被稱為生成器(generator)。 跟普通函數(shù)不同的是,生成器是一個(gè)返回迭代器的函數(shù),只能用于迭代操作,更簡(jiǎn)單點(diǎn)理解生成器就是一個(gè)迭代器。 在調(diào)用生成器運(yùn)行的過(guò)程中,每次遇到 yield 時(shí)函數(shù)會(huì)暫停并保存當(dāng)前所有的運(yùn)行信息,返回 yield 的值, 并在下一次執(zhí)行 next() 方法時(shí)從當(dāng)前位置繼續(xù)運(yùn)行。 調(diào)用一個(gè)生成器函數(shù),返回的是一個(gè)迭代器對(duì)象。

網(wǎng)上例子很多,所有例子一開(kāi)始就是這樣的代碼:

# ?。。∵@種代碼 建議別看,因?yàn)橐晕矣H身經(jīng)歷,初次理解生成器,看這樣的代碼根本看不懂的~
def evenNumber(max):
    n = 0
    while n < max:
        yield n
        n += 2
for i in evenNumber(10):
    print(i)

一會(huì)兒我把上述代碼重新寫(xiě)下。

在此之前,大家還是需要掌握什么是generator(生成器)。

generator(生成器)

最簡(jiǎn)單的創(chuàng)建一個(gè)生成器的方式,只要把一個(gè)列表生成式的 [] 改成 () ,就創(chuàng)建了一個(gè)generator:

List  = [i*2 for i in range(10)]
print(List)
#[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
g = (x*2 for x in range(10))
print(g)
#<generator object <genexpr> at 0x000001CBA42F3C10>

生成器(generator)能夠迭代的關(guān)鍵是它有一個(gè)next()方法,工作原理就是通過(guò)重復(fù)調(diào)用next()方法,直到捕獲一個(gè)異常。試一下:

g = (x*2 for x in range(10))
print(g.__next__())
# 0
print(g.__next__())
# 2
print(g.__next__())
# 4
#... ...

第二種方法就是, 如果一個(gè)函數(shù)中包含 yield 關(guān)鍵字,那么這個(gè)函數(shù)就不再是一個(gè)普通函數(shù),而是一個(gè)generator。調(diào)用函數(shù)就是創(chuàng)建了一個(gè)生成器(generator)對(duì)象。

著重講一下第二種方法,先看代碼,為了便于理解,我不寫(xiě)循環(huán),寫(xiě)一個(gè)生成器函數(shù):

def gen_example():
    print ('第1次執(zhí)行啦~,還沒(méi)到第一個(gè)yield!')
    yield '我是第1個(gè)遇見(jiàn)的yield,你遇到我就要返回'
    print ('第2次執(zhí)行啦~,還沒(méi)到第二個(gè)yield')
    yield '我是第2個(gè)遇見(jiàn)的yield,你遇到我就要返回'
    print ('第3次執(zhí)行啦,我運(yùn)行完 函數(shù)就執(zhí)行完畢啦~')
for i in gen_example():
    print(i)
    print("--------分割線--------")

執(zhí)行結(jié)果:

第1次執(zhí)行啦~,還沒(méi)到第一個(gè)yield!
我是第1個(gè)遇見(jiàn)的yield,你遇到我就要返回
--------分割線--------
第2次執(zhí)行啦~,還沒(méi)到第二個(gè)yield
我是第2個(gè)遇見(jiàn)的yield,你遇到我就要返回
--------分割線--------
第3次執(zhí)行啦,我運(yùn)行完 函數(shù)就執(zhí)行完畢啦~

過(guò)程詳解:

第一次for 循環(huán)執(zhí)行到y(tǒng)ield結(jié)束 ,只執(zhí)行了這兩句代碼:

在這里插入圖片描述

第二次循環(huán) 是從上一次的yield結(jié)束地方開(kāi)始執(zhí)行, 到下一個(gè)yield結(jié)束(一定要多讀幾遍理解哦):

在這里插入圖片描述

第三次循環(huán)是,從第二次遇見(jiàn)的yield結(jié)束地方開(kāi)始執(zhí)行,一直到下一個(gè)yield結(jié)束(沒(méi)有yield,自動(dòng)執(zhí)行結(jié)束)

在這里插入圖片描述

通過(guò)上述規(guī)律我們不難發(fā)現(xiàn),yield相當(dāng)于 return 返回一個(gè)值,并且記住這個(gè)返回的位置,下次迭代時(shí),代碼從yield的下一條語(yǔ)句開(kāi)始執(zhí)行!

為了驗(yàn)證這個(gè)規(guī)律 我把本文開(kāi)頭的代碼 重新寫(xiě)下,用更容易懂的方式:

def evenNumber(max):
    n = 0
    while n < max:
        yield n
        print("第二次是從這里開(kāi)始的")
        n += 2
        print(f"n在第二次是{n}")
for i in evenNumber(2):
    print(i)
    print("--------分割線--------")

執(zhí)行結(jié)果:

0
--------分割線--------
第二次是從這里開(kāi)始的
n在第二次是2

輸出:0, 是怎么得到的呢?函數(shù)第一次執(zhí)行,遇到y(tǒng)ield 就返回,所以此時(shí)就打印0。

在這里插入圖片描述

第二次是從這里開(kāi)始的,n在第二次是2 這又是怎么得到的呢?執(zhí)行yield后面的這部分,然后又進(jìn)入循環(huán),while循環(huán)條件都不滿足,執(zhí)行結(jié)束。

實(shí)際第二次沒(méi)有返回值。如果你細(xì)心點(diǎn)就會(huì)發(fā)現(xiàn),第二次輸出都沒(méi)有分割線的內(nèi)容:

在這里插入圖片描述

在這里插入圖片描述

既然 第二次打印都終止了,為什么沒(méi)報(bào)錯(cuò)? 好問(wèn)題!因?yàn)檎{(diào)用next()來(lái)執(zhí)行生成器則會(huì)報(bào)錯(cuò),如果使用for循環(huán)遍歷,for循環(huán)會(huì)自動(dòng)捕獲該異常,直接停止遍歷。

def evenNumber(max):
    n = 0
    while n < max:
        yield n
        print("第二次是從這里開(kāi)始的")
        n += 2
        print(f"n在第二次是{n}")
g = evenNumber(2)
print(g.__next__())
print(g.__next__())

執(zhí)行結(jié)果,調(diào)用next方法就會(huì)報(bào)錯(cuò):

0
第二次是從這里開(kāi)始的
n在第二次是2
Traceback (most recent call last):
  File "test.py", line 17, in <module>
    print(g.__next__())
StopIteration
***Repl Closed***

所以,就印證了我們的結(jié)論~! 現(xiàn)在來(lái)看一些簡(jiǎn)單的生成器函數(shù)的例子,是不是就一下懂了。

如果看到這里還是沒(méi)懂 ,留言吧,我會(huì)好好反思我自;

留個(gè)小作業(yè) 大家可以試試分析下斐波那契數(shù)列的過(guò)程。

def fab(max): 
    n, a, b = 0, 0, 1 
    while n < max: 
        yield b     
        a, b = b, a + b 
        n = n + 1
for n in fab(5): 
    print n

其它補(bǔ)充

如何判斷是不是 生成器函數(shù)?

使用 isgeneratorfunction 判斷函數(shù)是否是 generator 函數(shù)

from inspect import isgeneratorfunction 
print(isgeneratorfunction(fab) )
#True

為什么生成器函數(shù)中的return 不能返回值?

先看代碼:

def evenNumber(max):
    n = 0
    while n < max:
        yield n
        print("第二次是從這里開(kāi)始的")
        n += 2
        print(f"n在第二次是{n}")
        return 10
for i in evenNumber(10):
    print(i)
    print("--------分割線--------")

執(zhí)行結(jié)果:

0
--------分割線--------
第二次是從這里開(kāi)始的
n在第二次是2
***Repl Closed***

為什么 我的return 的值 沒(méi)有在最后一次打印出來(lái)呢? 在官方文檔中是這樣解釋的:

在這里插入圖片描述

python生成器函數(shù)中return 的作用就是終止生成器。

表示生成器運(yùn)行完成了,可以結(jié)束了。然后生成器會(huì)拋出一個(gè)StopIteration的異常。

而for循環(huán)能夠檢測(cè)到這個(gè)異常,于是結(jié)束循環(huán),也不報(bào)錯(cuò)。但是__next__()就會(huì)報(bào)錯(cuò)哦~

到此這篇關(guān)于Python中的yield全方位解讀的文章就介紹到這了,更多相關(guān)Python中的yield內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Python 權(quán)限控制模塊 Casbin

    Python 權(quán)限控制模塊 Casbin

    這篇文章主要介紹了Python 權(quán)限控制模塊 Casbin,Casbin是一個(gè)強(qiáng)大的、高效的開(kāi)源訪問(wèn)控制框架,其權(quán)限管理機(jī)制支持多種訪問(wèn)控制模型,更多相關(guān)內(nèi)容感興趣的朋友可以參考下面文章內(nèi)容
    2022-06-06
  • typing.Dict和Dict的區(qū)別及它們?cè)赑ython中的用途小結(jié)

    typing.Dict和Dict的區(qū)別及它們?cè)赑ython中的用途小結(jié)

    當(dāng)在 Python 函數(shù)中聲明一個(gè) dictionary 作為參數(shù)時(shí),我們一般會(huì)把 key 和 value 的數(shù)據(jù)類型聲明為全局變量,而不是局部變量。,這篇文章主要介紹了typing.Dict和Dict的區(qū)別及它們?cè)赑ython中的用途小結(jié),需要的朋友可以參考下
    2023-06-06
  • 詳解基于python的圖像Gabor變換及特征提取

    詳解基于python的圖像Gabor變換及特征提取

    這篇文章主要介紹了基于python的圖像Gabor變換及特征提取,本文通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2020-10-10
  • 如何使用五行Python代碼輕松實(shí)現(xiàn)批量摳圖

    如何使用五行Python代碼輕松實(shí)現(xiàn)批量摳圖

    簡(jiǎn)單來(lái)說(shuō),摳圖就是將照片的主體人或物品從圖片中摳出來(lái),以便貼到別處使用,下面這篇文章主要給大家介紹了關(guān)于如何使用五行Python代碼輕松實(shí)現(xiàn)批量摳圖的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-04-04
  • 三分鐘教會(huì)你用Python+OpenCV批量裁剪xml格式標(biāo)注的圖片

    三分鐘教會(huì)你用Python+OpenCV批量裁剪xml格式標(biāo)注的圖片

    最近學(xué)習(xí)網(wǎng)絡(luò)在線課程的過(guò)程中,為了方便課后復(fù)習(xí),使用手機(jī)截取了大量的圖片,下面這篇文章主要給大家介紹了如何通過(guò)三分鐘教會(huì)你用Python+OpenCV批量裁剪xml格式標(biāo)注圖片的相關(guān)資料,需要的朋友可以參考下
    2022-01-01
  • PyCharm Python Console中文輸出亂碼問(wèn)題及解決

    PyCharm Python Console中文輸出亂碼問(wèn)題及解決

    這篇文章主要介紹了PyCharm Python Console中文輸出亂碼問(wèn)題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-07-07
  • python中調(diào)試或排錯(cuò)的五種方法示例

    python中調(diào)試或排錯(cuò)的五種方法示例

    這篇文章主要給大家介紹了關(guān)于python中調(diào)試或排錯(cuò)的五種方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用Python具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-09-09
  • python文件讀寫(xiě)操作小結(jié)

    python文件讀寫(xiě)操作小結(jié)

    python文件對(duì)象提供了三個(gè)“讀”方法:?read()、readline()?和?readlines(),每種方法可以接受一個(gè)變量以限制每次讀取的數(shù)據(jù)量,這篇文章主要介紹了python文件讀寫(xiě)小結(jié),需要的朋友可以參考下
    2022-02-02
  • 5個(gè)Python中實(shí)現(xiàn)文字轉(zhuǎn)語(yǔ)音模塊的使用講解

    5個(gè)Python中實(shí)現(xiàn)文字轉(zhuǎn)語(yǔ)音模塊的使用講解

    這篇文章主要為大家詳細(xì)介紹了5個(gè)Python中實(shí)現(xiàn)文字轉(zhuǎn)語(yǔ)音模塊的使用,文中的示例代碼講解詳細(xì),對(duì)我們深入掌握Python有一定的幫助,需要的可以參考下
    2023-11-11
  • Pandas實(shí)現(xiàn)數(shù)據(jù)類型轉(zhuǎn)換的一些小技巧匯總

    Pandas實(shí)現(xiàn)數(shù)據(jù)類型轉(zhuǎn)換的一些小技巧匯總

    這篇文章主要給大家匯總介紹了關(guān)于Pandas實(shí)現(xiàn)數(shù)據(jù)類型轉(zhuǎn)換的一些小技巧,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2018-05-05

最新評(píng)論