簡體   English   中英

在try…except塊中處理generator.send()時發生異常

[英]Exception while handling generator.send() in try…except block

filename = 'tempfile'

def tail(filename):
    fd = open(filename)
    while True:
        line = fd.readline()
        if not line:
            continue
        else:
            if filename != 'uh':
                yield line
            else:
                print 'Returning f to close the file'
                yield fd


try:
    genObj = tail(filename) 
    valfromgen= genObj.next()
    while valfromgen:
        print valfromgen
        valfromgen= genObj.next()
except:
    traceback.print_exc()
    try:
        fd_Got_Back = genObj.send('uh')
        fd_Got_Back.close()
    except:
        traceback.print_exc()

代碼的意圖:我僅在生成器函數中打開了文件,而不是在文件外部打開了文件,但是,我可能想通過使用“發送”來關閉文件在生成器函數之外的文件。

我想做的是:從unix復制tail -f

我要如何做:

  1. 在讀取模式下打開一個臨時文件。
  2. 如果臨時文件中寫入了1行(我將繼續手動編寫並使用記事本保存tempfile) ,請產生新行。

問題:

問題是,如果我在命令提示符下運行此Python代碼時按Ctrl + C (即SIGTERM) ,則試圖檢查如何從此python代碼關閉打開的臨時文件。 為了模擬這一點,我已經在打開了臨時文件tail功能,每當有一個例外(這將是由系統當我按下Ctrl + C被升高)時,控制應在第1去除了。 然后,從這里開始,我嘗試將值uh發送到生成器函數tail ,以便它應產生已打開文件的文件描述符,可用於關閉已打開的tempfile。

PS:我希望有一個解決方案,其中我只能在generator函數中打開文件,而不能在它外部打開。

我認為您誤解了“發送”的工作方式。 發送只是使生成器在下一次迭代時產生該值。 它不會更改原始參數的值。 然后,您可以出於某些目的使用該產生的值。 因此,您可以編寫代碼:

filename = 'tempfile'

def tail(filename):
    fd = open(filename)
    while True:
        line = fd.readline()
        if not line:
            continue
        else:
            x = (yield line)
            if (x == 'uh'):
                print 'Returning f to close the file'
                yield fd


try:
    genObj = tail(filename) 
    valfromgen= genObj.next()
    while valfromgen:
        print valfromgen
        valfromgen= genObj.next()
except:
    traceback.print_exc()
    try:
        genObj.send('uh').close()
    except:
        traceback.print_exc()

我已經解決了卡住的問題,並提出了以下解決方案:-

  1. 當我按Ctrl + C(在Windows上)時,KeyboardInterrupt實際上發生在fd.readline()中。 因此,我只是嘗試了一下...除了那里,所以只要按Ctrl + C,生成器函數就會產生文件描述符。 如果沒有KeyBoardInterrupt,那么只需從tempfile打印一個新讀取的行
  2. 使用主體中的isinstance()檢查此文件描述符,如果發現它是文件,那么我將關閉文件以及生成器

PS :(此KeyboardInterrupt在Linux上可能會有所不同。可能會引發SigTerm,但請檢查。因此,為了使代碼通用,只需刪除KeyBoard Interrupt並正常使用即可,除非)

import sys,  traceback

filename = 'tempfile'

def tail(filename):
    fd = open(filename)
    while True:
        try:
            line = fd.readline()
        except KeyboardInterrupt:
            print 'keyboard interrupt here'
            yield fd
        if not line:
            continue
        else:
            yield line


try:
    genObj = tail(filename) 
    valfromgen= genObj.next()
    while valfromgen:       
        if isinstance(valfromgen, file):
            print 'Closing this file now as `tail` yielded a file descriptor'
            valfromgen.close()
            genObj.close()
            break
        print 'Yielded line: ', valfromgen
        valfromgen= genObj.next()

    print 'Just in order to check that things are in order, the following line will raise StopIteration. If it raises, it means we are good.'
    print genObj.next()
except:
    traceback.print_exc()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM