繁体   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