第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號(hào)安全,請(qǐng)及時(shí)綁定郵箱和手機(jī)立即綁定
已解決430363個(gè)問題,去搜搜看,總會(huì)有你想問的

如何防止或捕獲yield 調(diào)用函數(shù)中的StopIteration 異常?

如何防止或捕獲yield 調(diào)用函數(shù)中的StopIteration 異常?

MMMHUHU 2023-10-26 10:45:08
我們的庫(kù)之一中的生成器返回函數(shù)(即其中包含yield語句的函數(shù))由于未處理的StopIteration異常而導(dǎo)致某些測(cè)試失敗。為了方便起見,在這篇文章中我將此函數(shù)稱為buggy。我一直無法找到一種方法來buggy防止異常(不影響函數(shù)的正常運(yùn)行)。同樣,我還沒有找到一種方法來捕獲異常(使用try/ except)buggy。(客戶端代碼usingbuggy可以捕獲此異常,但這發(fā)生得太晚了,因?yàn)榫哂姓_處理導(dǎo)致此異常的條件所需信息的代碼是函數(shù)buggy。)我正在使用的實(shí)際代碼和測(cè)試用例太復(fù)雜,無法在此處發(fā)布,因此我創(chuàng)建了一個(gè)非常簡(jiǎn)單但又極其人為的玩具示例來說明問題。一、模塊功能buggy:# mymod.pyimport csv  # essential!def buggy(csvfile):    with open(csvfile) as stream:        reader = csv.reader(stream)        # how to test *here* if either stream is at its end?        for row in reader:            yield row正如注釋所示,csv模塊(來自 Python 3.x 標(biāo)準(zhǔn)庫(kù))的使用是這個(gè)問題1的一個(gè)基本特征。該示例的下一個(gè)文件是一個(gè)腳本,旨在代表“客戶端代碼”。換句話說,除了這個(gè)例子之外,這個(gè)腳本的“真正目的”在很大程度上是無關(guān)緊要的。它在示例中的作用是提供一種簡(jiǎn)單、可靠的方法來引出函數(shù)的問題buggy。(例如,它的一些代碼可以重新用于測(cè)試套件中的測(cè)試用例。)#!/usr/bin/env python3# myscript.pyimport sysimport mymoddef print_row(row):    print(*row, sep='\t')def main(csvfile, mode=None):    if mode == 'first':        print_row(next(mymod.buggy(csvfile)))    else:        for row in mymod.buggy(csvfile):            print_row(row)if __name__ == '__main__':    main(*sys.argv[1:])該腳本將 CSV 文件的路徑作為強(qiáng)制參數(shù),以及可選的第二個(gè)參數(shù)。如果省略第二個(gè)參數(shù),或者它不是字符串"first",則腳本將以TSVstdout格式打印到CSV 文件中的信息。如果第二個(gè)參數(shù)是字符串,則僅打印第一行中的信息。"first"當(dāng)使用空文件和字符串作為參數(shù)2StopIteration調(diào)用腳本時(shí),會(huì)出現(xiàn)我試圖捕獲的異常。myscript.py"first"
查看完整描述

2 回答

?
MMTTMM

TA貢獻(xiàn)1869條經(jīng)驗(yàn) 獲得超4個(gè)贊

mcernak很好地解決并描述了您遇到的問題


然而,這個(gè)問題背后存在一個(gè)設(shè)計(jì)問題:調(diào)用者有時(shí)并不期望生成器,而是非空迭代器


從另一個(gè)角度來看,如果文件丟失了怎么辦?對(duì)于函數(shù)句柄并返回一些哨兵或?qū)⑵涮嵘o調(diào)用者是否更有IOError意義open?


不要試圖強(qiáng)制你的生成器與虐待它的調(diào)用者一起工作,而是考慮


提供兩個(gè)函數(shù)(一個(gè)可以調(diào)用另一個(gè))

為生成器的最大行數(shù)提供一個(gè)參數(shù)(可能是最好的)

# mymod.py


import csv

import itertools

def notbuggy(csvfile, max_rows=None):

    with open(csvfile) as stream:

        yield from itertools.islice(csv.reader(stream), max_rows)

#!/usr/bin/env python3

# myscript.py


import sys

import mymod


def print_row(row):

    print(*row, sep='\t')


def main(csvfile, mode=None):

    max_rows = 1 if mode == "first" else None

    for row in mymod.notbuggy(csvfile, max_rows):

        print_row(row)


if __name__ == '__main__':

    main(*sys.argv[1:])


使用時(shí)next(),調(diào)用邏輯必須同意以下之一


永遠(yuǎn)不要在空的可迭代對(duì)象上調(diào)用它(先檢查文件?)

處理來自生成器的異常(StopIteration一些自定義Exception)

處理一些空的哨兵(也許""是一些字符串,None或object..)

然而,調(diào)用者沒有執(zhí)行這些操作,因此保證沒有很好地設(shè)置!


如果調(diào)用者想要多個(gè)行或?qū)⒖丈诒忉尀橹翟趺崔k?除非這些在文檔中以某種方式傳達(dá),否則調(diào)用者總是可以誤用函數(shù)并且不知道為什么它會(huì)出現(xiàn)意外的行為。


>>> next(iter(()))

Traceback (most recent call last):

  File "<stdin>", line 1, in <module>

StopIteration

>>> g = iter((1,))

>>> next(g)

1

>>> next(g)

Traceback (most recent call last):

  File "<stdin>", line 1, in <module>

StopIteration

>>> print_row("STOP SENTINEL")

S   T   O   P       S   E   N   T   I   N   E   L


查看完整回答
反對(duì) 回復(fù) 2023-10-26
?
喵喵時(shí)光機(jī)

TA貢獻(xiàn)1846條經(jīng)驗(yàn) 獲得超7個(gè)贊

StopIteration您可以通過以下方式在函數(shù)的詞法范圍內(nèi)捕獲異常buggy:


import csv  # essential!


def buggy(csvfile):

    with open(csvfile) as stream:


        reader = csv.reader(stream)


        try:

            yield next(reader)

        except StopIteration:

            yield 'dummy value'


        for row in reader:

            yield row

您基本上手動(dòng)從迭代器請(qǐng)求第一個(gè)值reader,然后

  • 如果成功,將從 csv 文件中讀取第一行并將其提供給buggy函數(shù)的調(diào)用者

  • 如果失敗,就像空 csv 文件的情況一樣,dummy value會(huì)產(chǎn)生一些字符串,以防止函數(shù)的調(diào)用者buggy崩潰

之后,如果 csv 文件不為空,則將在 for 循環(huán)中讀?。ú⑸桑┦S嗟男?。


編輯:為了說明為什么問題中提到的其他變體mymod.py不起作用,我添加了一些打印語句:

import csv  # essential!


def buggy(csvfile):

    with open(csvfile) as stream:


        reader = csv.reader(stream)


        try:

            print('reading first row')

            firstrow = next(reader)

        except StopIteration:

            print('no first row exists')

            firstrow = None


        if firstrow != None:

            print('yielding first row: ' + firstrow)

            yield firstrow


        for row in reader:

            print('yielding next row: ' + row)

            yield row


        print('exiting function open')

運(yùn)行它會(huì)給出以下輸出:


% ./myscript.py empty_input.csv first

reading first row

no first row exists

exiting function open

Traceback (most recent call last):

  File "myscript.py", line 15, in <module>

    main(*sys.argv[1:])

  File "myscript.py", line 9, in main

    print_row(next(mymod.buggy(csvfile)))

這表明,如果輸入文件為空,第一個(gè)try..except塊會(huì)正確處理StopIteration異常,并且buggy函數(shù)會(huì)正常繼續(xù)。

在這種情況下,調(diào)用者得到的異常buggy是由于該buggy函數(shù)在完成之前不會(huì)產(chǎn)生任何值。


查看完整回答
反對(duì) 回復(fù) 2023-10-26
  • 2 回答
  • 0 關(guān)注
  • 212 瀏覽
慕課專欄
更多

添加回答

舉報(bào)

0/150
提交
取消
微信客服

購(gòu)課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動(dòng)學(xué)習(xí)伙伴

公眾號(hào)

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號(hào)