1
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()

代码的意图:我只在生成器函数中打开了文件,而不是在它之外,但是,我想通过使用“发送”来关闭生成器函数之外的文件。

我正在尝试做的事情:tail -f从 unix 复制。

我想怎么做:

  1. 以读取模式打开临时文件。
  2. 如果临时文件中写入了 1 个新行(我将继续手动编写并使用记事本保存临时文件),则生成新写入的行。

问题:

问题是我正在尝试检查如何在此 Python 代码在命令提示符下运行时按Ctrl+ C (即 SIGTERM)关闭此 Python 代码中打开的临时文件。为了模拟这一点,我在tail函数中打开了临时文件,每当出现异常(当我按下+时系统将引发异常)CtrlC时,控件应该在第一个除外。然后,从这里开始,我尝试向uh生成器函数发送一个值tail,以便它产生打开的文件的文件描述符,我可以使用它来关闭打开的临时文件。

PS:我希望有一个解决方案,我只在生成器函数中而不是在它之外打开文件。

4

2 回答 2

0

我认为您误解了“发送”的工作原理。发送只是使生成器在下一次迭代中产生该值。它不会改变原始参数的值。然后,您可以将产生的值用于某些目的。所以你可以制作你的代码:

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()
于 2012-08-16T21:30:52.460 回答
0

我已经弄清楚了我被卡住的问题,我想出了这个解决方案:-

  1. 当我按 Ctrl + C(在 Windows 上)时,KeyboardInterrupt 实际上发生在 fd.readline() 中。所以,我只是在那里放置了一个 try...except ,以便生成器函数在按下 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()

于 2012-08-17T08:03:32.563 回答