国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專(zhuān)欄INFORMATION COLUMN

Python 學(xué)習(xí)筆記 關(guān)于協(xié)程

VishKozus / 837人閱讀

摘要:協(xié)程定義協(xié)程是指一個(gè)過(guò)程,這個(gè)過(guò)程與調(diào)用方協(xié)作,產(chǎn)出由調(diào)用方提供的值。當(dāng)?shù)玫娇刂茩?quán)時(shí),會(huì)阻塞,同時(shí)等待終止。終止協(xié)程的方法該方法致使生成器在暫停的表達(dá)式處拋出異常。

協(xié)程

定義:協(xié)程是指一個(gè)過(guò)程,這個(gè)過(guò)程與調(diào)用方協(xié)作,產(chǎn)出由調(diào)用方提供的值。(協(xié)程中必定含有一條yield語(yǔ)句)

協(xié)程與生成器類(lèi)似,都是定義體內(nèi)包含yield關(guān)鍵字的函數(shù)。不過(guò),在協(xié)程中,yield通常出現(xiàn)在表達(dá)式的右邊(例如,data = yield),可以產(chǎn)出值,也可以不產(chǎn)出。

生成器不可以返回值,如果生成器中給return語(yǔ)句提供值,會(huì)拋出SyntaxError異常;

python新引入yield from 語(yǔ)句,可以把復(fù)雜的生成器重構(gòu)成小型的嵌套生成器,省去了大量樣板代碼。

三個(gè)方法:

. send() 方法,可以讓調(diào)用方給協(xié)程發(fā)送數(shù)據(jù),發(fā)送的數(shù)據(jù)會(huì)成為協(xié)程函數(shù)中 yield 表達(dá)式的值。

.throw() 方法,可以讓調(diào)用方拋出異常

.close() 方法,可以讓調(diào)用方終止協(xié)程

四個(gè)狀態(tài):

"GEN_CREATED" 等待開(kāi)始執(zhí)行

"GEN_RUNNING" 解釋器正在執(zhí)行

"GEN_SUSPENDED" 在yield表達(dá)式處暫停

"GEN_CLOASED" 執(zhí)行結(jié)束

協(xié)程只能處于這四個(gè)狀態(tài)中的一個(gè),當(dāng)前狀態(tài)可以由 inspect.getgeneratorstate(...)函數(shù)獲取

因?yàn)閟end() 方法的參數(shù)會(huì)成為暫停的yield表達(dá)式的值,所以,僅當(dāng)協(xié)程處于暫停狀態(tài)時(shí)才能調(diào)用send()方法

協(xié)程需要被預(yù)激,預(yù)激是通過(guò)next()函數(shù)進(jìn)行

給協(xié)程添加預(yù)激裝飾器 functools.wraps(),可以省去協(xié)程的預(yù)激過(guò)程。

yield from

在生成器gen中使用yield from subgen()時(shí),subgen()會(huì)得到當(dāng)前的控制權(quán),把產(chǎn)出的值傳給gen的調(diào)用方,即調(diào)用方可以直接跳過(guò)gen控制subgen。當(dāng)subgen得到控制權(quán)時(shí),gen會(huì)阻塞,同時(shí)等待subgen終止。

一個(gè)小例子:

def chain(*iters):
    for iter in iters:
        yield from iter

lst_1 = "abc"
lst_2 = "987"
print(list(chain(lst_1, lst_2)))

運(yùn)行結(jié)果:

["a", "b", "c", "9", "8", "7"]

這個(gè)例子還可以改寫(xiě)為:

def chain():
    yield from "abc"
    yield from "987"

輸出結(jié)果是一樣的。

yield from 的主要功能是打開(kāi)雙向通道,把最外層的調(diào)用方與最內(nèi)層的子生成器連接起來(lái),這樣,二者可以直接發(fā)送和產(chǎn)生值,甚至可以直接傳入異常。

一個(gè)復(fù)雜的例子,計(jì)算中學(xué)生的平均身高和體重:

from collections import namedtuple

Result = namedtuple("Result", "count average")


# 子生成器
def averager():  # <1>
    total = 0.0
    count = 0
    average = None
    while True:
        term = yield  # <2>
        if term is None:  # <3>
            break
        total += term
        count += 1
        average = total/count
    return Result(count, average)  # <4>


# 委派生成器
def grouper(results, key):  # <5>
    while True:  # <6>
        results[key] = yield from averager()  # <7>


# 客戶(hù)端代碼,即調(diào)用端
def main(data):  # <8>
    results = {}
    for key, values in data.items():
        group = grouper(results, key)  # <9>
        next(group)  # <10>
        for value in values:
            group.send(value)  # <11>
        group.send(None)  # important! <12>

    # print(results)  # uncomment to debug
    report(results)


# 輸出報(bào)告
def report(results):
    for key, result in sorted(results.items()):
        group, unit = key.split(";")
        print("{:2} {:5} averaging {:.2f}{}".format(
              result.count, group, result.average, unit))


data = {
    "girls;kg":
        [40.9, 38.5, 44.3, 42.2, 45.2, 41.7, 44.5, 38.0, 40.6, 44.5],
    "girls;m":
        [1.6, 1.51, 1.4, 1.3, 1.41, 1.39, 1.33, 1.46, 1.45, 1.43],
    "boys;kg":
        [39.0, 40.8, 43.2, 40.8, 43.1, 38.6, 41.4, 40.6, 36.3],
    "boys;m":
        [1.38, 1.5, 1.32, 1.25, 1.37, 1.48, 1.25, 1.49, 1.46],
}


if __name__ == "__main__":
    main(data)

運(yùn)行結(jié)果:

 9 boys  averaging 40.42kg
 9 boys  averaging 1.39m
10 girls averaging 42.04kg
10 girls averaging 1.43m

委派生成器grouper()只是起到一個(gè)傳輸數(shù)據(jù)的作用,沒(méi)有進(jìn)行任何的數(shù)據(jù)處理。

生成器中都有一個(gè)無(wú)限循環(huán) while True: 這個(gè)無(wú)限循環(huán)表明,只要調(diào)用方不斷把值發(fā)送給這個(gè)協(xié)程,它就會(huì)一直接收值,然后生成結(jié)果。該循環(huán)結(jié)束條件:

調(diào)用方在協(xié)程上顯式調(diào)用 .close() 方法,

或者沒(méi)有對(duì)協(xié)程的引用,而被垃圾回收程序回收時(shí),這個(gè)協(xié)程才會(huì)終止。

終止協(xié)程的方法

generator.close()

該方法致使生成器在暫停的 yield 表達(dá)式處拋出 GeneratorExit 異常。

如果生成器處理了這個(gè)異常,生成器一定不能產(chǎn)生值,否則解釋器會(huì)拋出RuntimeError異常。

如果生成器沒(méi)有處理這個(gè)異常,或者拋出StopIteration異常,即生成器已經(jīng)運(yùn)行到最后,調(diào)用方也不會(huì)報(bào)錯(cuò)。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/42346.html

相關(guān)文章

  • Python 中的進(jìn)程、線(xiàn)程、協(xié)程、同步、異步、回調(diào)

    摘要:進(jìn)程和線(xiàn)程究竟是什么東西傳統(tǒng)網(wǎng)絡(luò)服務(wù)模型是如何工作的協(xié)程和線(xiàn)程的關(guān)系和區(qū)別有哪些過(guò)程在什么時(shí)間發(fā)生在剛剛結(jié)束的上海站,來(lái)自七牛云存儲(chǔ)的高級(jí)工程師許智翔帶來(lái)了關(guān)于的分享中的進(jìn)程線(xiàn)程協(xié)程同步異步回調(diào)。使用紅黑樹(shù)管理就緒隊(duì)列。 進(jìn)程和線(xiàn)程究竟是什么東西?傳統(tǒng)網(wǎng)絡(luò)服務(wù)模型是如何工作的?協(xié)程和線(xiàn)程的關(guān)系和區(qū)別有哪些?IO過(guò)程在什么時(shí)間發(fā)生? 在剛剛結(jié)束的 PyCon2014 上海站,來(lái)自七牛云...

    Forest10 評(píng)論0 收藏0
  • python基礎(chǔ)教程:異步IO 之 概念和歷史

    摘要:并發(fā)的方式有多種,多線(xiàn)程,多進(jìn)程,異步等。多線(xiàn)程和多進(jìn)程之間的場(chǎng)景切換和通訊代價(jià)很高,不適合密集型的場(chǎng)景關(guān)于多線(xiàn)程和多進(jìn)程的特點(diǎn)已經(jīng)超出本文討論的范疇,有興趣的同學(xué)可以自行搜索深入理解。 編程中,我們經(jīng)常會(huì)遇到并發(fā)這個(gè)概念,目的是讓軟件能充分利用硬件資源,提高性能。并發(fā)的方式有多種,多線(xiàn)程,多進(jìn)程,異步IO等。多線(xiàn)程和多進(jìn)程更多應(yīng)用于CPU密集型的場(chǎng)景,比如科學(xué)計(jì)算的時(shí)間都耗費(fèi)在CPU...

    BicycleWarrior 評(píng)論0 收藏0
  • 流暢的python讀書(shū)筆記-第十六章-攜(協(xié))程

    摘要:當(dāng)前狀態(tài)可以使用函數(shù)確定,該函數(shù)會(huì)返回下述字符串中的一個(gè)。解釋器正在執(zhí)行。打印消息,然后協(xié)程終止,導(dǎo)致生成器對(duì)象拋出異常。實(shí)例運(yùn)行完畢后,返回的值綁定到上。 協(xié)程 協(xié)程可以身處四個(gè)狀態(tài)中的一個(gè)。 當(dāng)前狀態(tài)可以使用inspect.getgeneratorstate(...) 函數(shù)確定,該函數(shù)會(huì)返回下述字符串中的一個(gè)。 GEN_CREATED  等待開(kāi)始執(zhí)行。 GEN_RUNNING  解...

    wanglu1209 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<