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

資訊專欄INFORMATION COLUMN

流暢的python讀書筆記-第十六章-攜(協(xié))程

wanglu1209 / 3345人閱讀

摘要:當(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"
  等待開始執(zhí)行。

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

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

"GEN_CLOSED"
  執(zhí)行結(jié)束。

def simple_coro2(a):
    print("-> Started: a =", a)


    b = yield a  #等著賦值b 把a(bǔ)甩出去
    print("-> Received: b =", b)
    c = yield a + b
    print("-> Received: c =", c)


my_coro_2 = simple_coro2(14)

from inspect import getgeneratorstate

print(getgeneratorstate(my_coro_2))

print(next(my_coro_2))
getgeneratorstate(my_coro_2)


print(my_coro_2.send(28))

# 沒有yield 出來 所以沒有返回值
print(my_coro_2.send(99))

getgeneratorstate(my_coro_2)

getgeneratorstate 函數(shù)指明,處于 GEN_SUSPENDED 狀態(tài)(即協(xié)程在 yield 表達(dá)式處暫停)。

? 把數(shù)字 99 發(fā)給暫停的協(xié)程;計(jì)算 yield 表達(dá)式,得到 99,然后把那個(gè)數(shù)綁定給 c。
打印 -> Received: c = 99 消息,然后協(xié)程終止,導(dǎo)致生成器對(duì)象拋出
StopIteration 異常。

另一個(gè)案例
def averager():
    total = 0.0
    count = 0
    average = None
    while True:
        term = yield average
        total += term
        count += 1
        average = total / count


coro_avg = averager()

print(next(coro_avg))

print(coro_avg.send(10))

print(coro_avg.send(15))

print(coro_avg.send(20))

調(diào)用 next 函數(shù),預(yù)激協(xié)程。
? 這個(gè)無限循環(huán)表明,只要調(diào)用方不斷把值發(fā)給這個(gè)協(xié)程,它就會(huì)一直接收值,然后生
成結(jié)果。僅當(dāng)調(diào)用方在協(xié)程上調(diào)用 .close() 方法,或者沒有對(duì)協(xié)程的引用而被垃圾回收
程序回收時(shí),這個(gè)協(xié)程才會(huì)終止。
? 這里的 yield 表達(dá)式用于暫停執(zhí)行協(xié)程,把結(jié)果發(fā)給調(diào)用方;還用于接收調(diào)用方后面
發(fā)給協(xié)程的值,恢復(fù)無限循環(huán)。

終止協(xié)程和異常處理

發(fā)送某個(gè)哨符值,讓協(xié)程退出。
內(nèi)置的 None 和Ellipsis 等常量經(jīng)常用作哨符值。

Ellipsis 的優(yōu)點(diǎn)是,數(shù)據(jù)流中不太常有這個(gè)值。

throw

generator.throw(exc_type[, exc_value[, traceback]])

致使生成器在暫停的 yield 表達(dá)式處拋出指定的異常。

如果生成器處理了拋出的異常,代碼會(huì)向前執(zhí)行到下一個(gè) yield 表達(dá)式,而產(chǎn)出的值會(huì)成為調(diào)用 generator.throw方法得到的返回值。

generator.close()

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

如果生成器沒有處理這個(gè)異常,或者拋出了 StopIteration 異常(通常是指運(yùn)行到結(jié)尾),調(diào)用方不會(huì)報(bào)錯(cuò)。

如果收到 GeneratorExit 異常,生成器一定不能產(chǎn)出值,否則解釋器會(huì)拋出
RuntimeError 異常。

兩種停止方式

exc_coro.throw(ZeroDivisionError)
exc_coro.close()

讓協(xié)程返回值
from collections import namedtuple

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


def averager():
    total = 0.0
    count = 0
    average = None
    while True:
        term = yield
        if term is None:
            break
        total += term
        count += 1
        average = total / count
    return Result(count, average)


coro_avg = averager()
next(coro_avg)

coro_avg.send(30)
coro_avg.send(6.5)

try:
    coro_avg.send(None)
except StopIteration as exc:
    result = exc.value
    print(result)

捕獲 StopIteration 異常,獲取 averager 返回的值

yield from 結(jié)構(gòu)會(huì)在內(nèi)部自動(dòng)捕獲 StopIteration 異常。
這種處理方式與 for 循環(huán)處理 StopIteration 異常的方式一樣:循環(huán)機(jī)制使用用戶易于理解的方式處理異常。
對(duì) yield from 結(jié)構(gòu)來說,解釋器不僅會(huì)捕獲 StopIteration 異常,還會(huì)把value 屬性的值變成 yield from 表達(dá)式的值。
使用yield from

yield from 結(jié)構(gòu)唯一的作用是替代產(chǎn)出值的嵌套 for 循環(huán), 這句話不對(duì)

yield from 的主要功能是打開雙向通道,把最外層的調(diào)用方與最內(nèi)層的子生成器連接起來,

這樣二者可以直接發(fā)送和產(chǎn)出值,還可以直接傳入異常,

而不用在位于中間的協(xié)程中添加大量處理異常的樣板代碼。

有了這個(gè)結(jié)構(gòu),協(xié)程可以通過以前不可能的方式委托職責(zé)。

案例

委派生成器
  包含 yield from 表達(dá)式的生成器函數(shù)。

子生成器
  從 yield from 表達(dá)式中 部分獲取的生成器。這就是 PEP 380 的標(biāo)題
(“Syntax for Delegating to a Subgenerator”)中所說的“子生成器”(subgenerator)。

調(diào)用方
  PEP 380 使用“調(diào)用方”這個(gè)術(shù)語指代調(diào)用委派生成器的客戶端代碼。在不同的語境
中,我會(huì)使用“客戶端”代替“調(diào)用方”,以此與委派生成器(也是調(diào)用方,因?yàn)樗{(diào)用了子
生成器)區(qū)分開。

不使用yield from

from collections import namedtuple

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


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



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],
}




def main(data):
    result = {}

    for key, values in data.items():
        coro_avg = averager()
        next(coro_avg)
        for value in values:
            coro_avg.send(value)

        try:
            coro_avg.send(None)
        except StopIteration as exc:
            result[key] = exc.value

    print(result)



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

這里的try: catch stop異常要一直存在

用yiled from 及委派生成器作用

from collections import namedtuple

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


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



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],
}


def grouper(results):
    while True:
        res_obj = yield from averager()
        results.append(res_obj)




def main(data):
    results = []
    for key, values in data.items():

        coro_avg = grouper(results)
        next(coro_avg)

        for value in values:
            coro_avg.send(value)

        # 這個(gè)None是停止返回 哨兵
        coro_avg.send(None)


    print(results)

    # report(result)


# 輸出報(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))


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

官方的案例

from collections import namedtuple

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


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


# 委派生成器
def grouper(results, key):  # ?
    while True:  # ?
        results[key] = yield from averager()  # ?




# 客戶端代碼,即調(diào)用方
def main(data):  # ?
    results = {}
    for key, values in data.items():
        group = grouper(results, key)  # ?
        next(group)  # ?
        for value in values:
            group.send(value)  # ?
        group.send(None)  # 重要! #?

    print(results)  # 如果要調(diào)試,去掉注釋

    # 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)

? 至關(guān)重要的終止條件。如果不這么做,使用 yield from 調(diào)用這個(gè)協(xié)程的生成器會(huì)永
遠(yuǎn)阻塞。
? 返回的 Result 會(huì)成為 grouper 函數(shù)中 yield from 表達(dá)式的值

? 這個(gè)循環(huán)每次迭代時(shí)會(huì)新建一個(gè) averager 實(shí)例;每個(gè)實(shí)例都是作為協(xié)程使用的生成
器對(duì)象。
? grouper 發(fā)送的每個(gè)值都會(huì)經(jīng)由 yield from 處理,通過管道傳給 averager 實(shí)
例。grouper 會(huì)在 yield from 表達(dá)式處暫停,等待 averager 實(shí)例處理客戶端發(fā)來的
值。averager 實(shí)例運(yùn)行完畢后,返回的值綁定到 results[key] 上。while 循環(huán)會(huì)不斷
創(chuàng)建 averager 實(shí)例,處理更多的值。

yield from 結(jié)構(gòu)會(huì)在內(nèi)部自動(dòng)捕獲 StopIteration 異常。這種處理方
式與 for 循環(huán)處理 StopIteration 異常的方式一樣:循環(huán)機(jī)制使用用戶易于理解的方式
處理異常。對(duì) yield from 結(jié)構(gòu)來說,解釋器不僅會(huì)捕獲 StopIteration 異常,還會(huì)把
value 屬性的值變成 yield from 表達(dá)式的值。
總結(jié)

這里先不總結(jié) 帶我把協(xié)程 程序加進(jìn)去

如何使用協(xié)程在單個(gè)線程中管理并發(fā)活動(dòng)。

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

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

相關(guān)文章

  • 流暢python讀書筆記-第六章-使用一等函數(shù)實(shí)現(xiàn)設(shè)計(jì)模式

    摘要:在復(fù)雜的情況下,需要具體策略維護(hù)內(nèi)部狀態(tài)時(shí),可能需要把策略和享元模式結(jié)合起來。函數(shù)比用戶定義的類的實(shí)例輕量,而且無需使用享元模式,因?yàn)楦鱾€(gè)策略函數(shù)在編譯模塊時(shí)只會(huì)創(chuàng)建一次。 一等函數(shù)實(shí)現(xiàn)設(shè)計(jì)模式 經(jīng)典的策略模式定義 定義一系列算法,把它們一一封裝起來,并且使它們可以相互替換。本模式使得算法可以獨(dú)立于使用它的客戶而變化。 案例 假如一個(gè)網(wǎng)店制定了下述折扣規(guī)則。 有 1000 或以上積分...

    cnsworder 評(píng)論0 收藏0
  • python協(xié)2:yield from 從入門到精通

    摘要:于此同時(shí),會(huì)阻塞,等待終止。子生成器返回之后,解釋器會(huì)拋出異常,并把返回值附加到異常對(duì)象上,只是委派生成器恢復(fù)。實(shí)例運(yùn)行完畢后,返回的值綁定到上。這一部分處理調(diào)用方通過方法傳入的異常。之外的異常會(huì)向上冒泡。 上一篇python協(xié)程1:yield的使用介紹了: 生成器作為協(xié)程使用時(shí)的行為和狀態(tài) 使用裝飾器預(yù)激協(xié)程 調(diào)用方如何使用生成器對(duì)象的 .throw(...) 和 .close()...

    vpants 評(píng)論0 收藏0
  • python協(xié)1:yield 10分鐘入門

    摘要:協(xié)程定義協(xié)程的底層架構(gòu)是在中定義,并在實(shí)現(xiàn)的。為了簡化,我們會(huì)使用裝飾器預(yù)激協(xié)程。執(zhí)行上述代碼結(jié)果如下出錯(cuò)的原因是發(fā)送給協(xié)程的值不能加到變量上。示例使用和方法控制協(xié)程。 最近找到一本python好書《流暢的python》,是到現(xiàn)在為止看到的對(duì)python高級(jí)特性講述最詳細(xì)的一本。看了協(xié)程一章,做個(gè)讀書筆記,加深印象。 協(xié)程定義 協(xié)程的底層架構(gòu)是在pep342 中定義,并在python2...

    MartinDai 評(píng)論0 收藏0
  • 流暢python讀書筆記-第十四章-可迭代對(duì)象、迭代器和生成器

    摘要:可迭代的對(duì)象迭代器和生成器理念迭代是數(shù)據(jù)處理的基石。可迭代的對(duì)象與迭代器的對(duì)比從可迭代的對(duì)象中獲取迭代器標(biāo)準(zhǔn)的迭代器接口有兩個(gè)方法。此外,也沒有辦法還原迭代器。最終,函數(shù)的定義體返回時(shí),外層的生成器對(duì)象會(huì)拋出異常這一點(diǎn)與迭代器協(xié)議一致。 可迭代的對(duì)象、迭代器和生成器 理念 迭代是數(shù)據(jù)處理的基石。掃描內(nèi)存中放不下的數(shù)據(jù)集時(shí),我們要找到一種惰性獲取數(shù)據(jù)項(xiàng)的方式,即按需一次獲取一個(gè)數(shù)據(jù)項(xiàng)。這...

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

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

0條評(píng)論

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