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

コードの意図: ジェネレーター関数内のみでファイルを開き、その外側ではファイルを開きませんでしたが、おそらく 'send' を使用して、ジェネレーター関数の外側でそのファイルを閉じたいと考えています。

私がやろうとしていること: tail -funix からの複製。

私がやろうとしている方法:

  1. 読み取りモードで一時ファイルを開きます。
  2. tempfile に 1 つの新しい行が書き込まれている場合(手動で書き続け、メモ帳を使用して tempfile を保存します)、新しく書き込まれた行を生成します。

問題:

問題は、この Python コードがコマンド プロンプトで実行されているときにCtrl+ C (つまり SIGTERM)を押すと、この Python コードから開いている一時ファイルを閉じる方法を確認しようとしていることです。これをエミュレートするために、tail関数で一時ファイルを開きました。例外が発生するたびに( +を押すとシステムによって発生します)CtrlC、制御は最初の例外に移動する必要がありますuh次に、ここからジェネレーター関数に値を送信しようとしてtailいます。これにより、開いている一時ファイルを閉じるために使用できる、開いているファイルのファイル記述子が生成されます。

PS: ファイルをジェネレーター関数でのみ開き、その外側では開かないという解決策を期待しています。

4

2 に答える 2

0

私は立ち往生していた問題を理解し、この解決策を思いつきました:-

  1. Ctrl + C (Windows の場合) を押すと、実際には fd.readline() で KeyboardInterrupt が発生します。だから、私はそこを除いてtryを配置したので、ジェネレーター関数はCtrl + Cがヒットするたびにファイル記述子を生成します。KeyBoardInterrupt がない場合は、一時ファイルから新しく読み取った行を出力するだけです
  2. このファイル記述子は、本体で isinstance() を使用してチェックされ、ファイルであることが判明した場合は、ファイルとジェネレーターを閉じています

PS : (この KeyboardInterrupt は Linux では異なる場合があります。おそらく SigTerm が発生しますが、確認してください。したがって、コードを汎用にするためには、KeyBoard Interrupt を削除して、通常の except のみを使用してください)

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 に答える
0

「送信」の仕組みを誤解していると思います。Send は、ジェネレーターが次の反復でその値を生成するようにするだけです。元のパラメータの値は変更されません。その後、その生成された値を何らかの目的に使用できます。したがって、コードを作成できます:

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 に答える