异常,同时处理在尝试generator.send()... except块

问题描述:

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

意向的代码:我已经打开了,而不是外面的发电机功能的文件,但是,我想关闭该文件在生成器函数之外,可能使用“发送”。异常,同时处理在尝试generator.send()... except块

我在做什么:从unix复制tail -f

如何我试图做的事:

  1. 公开赛在读模式临时文件。
  2. 如果临时文件中写入了1条新行(我将继续使用记事本手动写入并保存临时文件),产生新写入的行。

问题:

的问题是,我想检查我如何从这个Python代码关闭打开的临时文件,如果我按按Ctrl +Ç(即SIGTERM)时此Python代码在命令提示符下运行。为了模仿这一点,我在tail功能打开的临时文件,每当有一个例外(这将被系统提出当我按下按Ctrl + Ç,控制应在去1 st除外。然后,从这里开始,我试图将值uh发送到生成器函数tail,以便它应该产生打开文件的文件描述符,我可以使用它来关闭打开的临时文件。 PS:我希望有一个解决方案,我只在生成器函数中打开文件,而不是在其外部。

+0

你大概意思'产量fd'而不是'产量F'。 – 2012-08-16 21:12:29

+0

@ Ihor:更正了 – GodMan 2012-08-16 21:15:48

+0

为什么不在试试打开文件? (然后关闭它在终于?) – GreenMatt 2012-08-16 21:49:05

我想通了,我被卡住的问题,我想出了这个解决方案: -

  1. 当我按Ctrl + C(在Windows上) ,KeyboardInterrupt实际上发生在fd.readline()中。所以,我只是放了一个try ...除了那里,这样,无论何时按Ctrl + C,生成器函数都会生成文件描述符。如果没有KeyBoardInterrupt,那么只需打印临时文件中新读取的一行
  2. 使用主体中的isinstance()检查此文件描述符,如果发现它是文件,则关闭文件以及发电机

PS:(这一个KeyboardInterrupt可能对Linux..probably SIGTERM变化将提高,但是,请检查。因此,为了使代码通用的,只是去掉键盘中断,并使用不同的只是正常的)

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

我认为你误解了“发送”的工作原理。发送只会导致生成器在其下一次迭代中生成该值。它不会更改原始参数的值。然后,您可以使用该产品的某些用途。所以,你可以让你的代码:

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() 
+0

我知道'with'语句,但正如我所说的,我正在尝试赋予生成器函数双重功能: 1.产生在运行时写入临时文件的新行 2.返回当我们希望它停止时,将文件解析器添加到打开的临时文件中。 – GodMan 2012-08-16 21:34:55

+0

对不起,你的问题意味着你只需要描述符来关闭文件。 – Baobabs 2012-08-16 22:10:11

+0

当然,如果在生成器代码运行时收到键盘中断(最可能的场景),那么对send()的调用将引发StopIteration异常。 – Baobabs 2012-08-16 22:41:55