2011-09-15 2 views
3

であるあなたは、このようなPythonでシンプルな発電機を持っていると仮定します。Pythonのジェネレータと収量:どのようにプログラムを並べるかを知ることは

更新:

def f(self):   
    customFunction_1(argList_1) 
    yield 
    customFunction_2(argList_2) 
    yield 
    customFunction_3(argList_3) 
    yield 
    ... 

私はF(呼び出し)別のスクリプトのように:

h=f() 
    while True: 
     try: 
      h.next() 
      sleep(2) 
     except KeyboardInterrupt: 
           ##[TODO] tell the last line in f() that was executed 

は、私は上記の[TODO]セクションを行うことができます方法はありますか?それはkeyboardInterruptが起こる前に実行されたf()の最後の行を知っていますか?

答えて

4

あなたはカウントする列挙()を使用することができます。

def f(): 

    ... 
    yield 
    ... 
    yield 
    ... 


for step, value in enumerate(f()): 
    try: 
     time.sleep(2) 
    except KeyboardInterrupt: 
     print(step) # step holds the number of the last executed function 

(あなたの例ではyield値が得られていないため、当然のvalue意志がNoneに)

または非常に明示的に使用して冗長表示:

def f(): 

    ... 
    yield 'first function finished' 
    ... 
    yield 'almost done' 
    ... 


for message in f(): 
    try: 
     time.sleep(2) 
    except KeyboardInterrupt: 
     print(message) 
+0

私は関数の定義を更新しました。実際には私のコードにあります。しかし、私はまだあなたのアプローチを使用することができます.. –

+0

ちょうどあなたのために簡単にし、 'enumerate()' – Remi

1

なぜ私はf()から私を得て、それを使用しないのですか?

val = h.next() 
+0

私の更新された機能をご覧ください。 –

1
def f(self):   
    sleep(10) 
    yield 
    sleep(10) 
    yield 
    sleep(10) 
    yield 


h=f() 
while True: 
    try: 
     h.next() 
    except KeyboardInterrupt: 
     stack_trace = sys.exc_info()[2] # first traceback points into this function where the exception was caught 
     stack_trace = stack_trace.tb_next # now we are pointing to where it happened (in this case) 
     line_no = stack_trace.tb_lineno # and here's the line number 
     del stack_trace     # get rid of circular references 

私はf()の内部で例外が発生した場合にのみ動作するため、sleep()への呼び出しをfに移動しました。

2

デバッグ目的の行番号を知りたい場合は、CPythonでh.gi_frame.f_linenoを使用できます。これは、次に実行され、1つのインデックスが付けられた行です。これがCPython以外のPython実装で動作するかどうかはわかりません。

h=f() 
while True: 
    try: 
     h.next() 
     sleep(2) 
    except KeyboardInterrupt: 
     print h.gi_frame.f_lineno - 1 # f_lineno is the line to be executed next. 

あなたはデバッグ目的のためにこれを知られたくない場合は、Remi's enumerate solutionがはるかにきれいです。

関連する問題