2016-12-27 2 views
1

ジェネレータとイテレータを使用するコードをデバッグする方法を教えてください。私は、ループにprint文を追加すると、ジェネレータ/イテレータを消費するため、残りのコードが壊れることがわかりました。要素を消費することなく、ジェネレータ/イテレータの "内容"を検査することは可能ですか?今、私はresultが何であるかを見てみたいデバッグジェネレータとイテレータ

result = map(func, x) 

は具体的には、私はこのような何かを持っています。私はまた、resultの各要素に関数を適用して返される値を見たいと思っています。私の実際のコードでは、私はこの関数の最小値を与えるresultの要素を取得しています:

best = min(result, key=my_key) 

min()は非常に便利ですが、私は間違った振る舞いを取得し、その理由を把握する必要がありますしています。このようなものをデバッグするために使用できるツールとは何ですか?

P.S.私はPyCharmを使用しています。私はインタラクティブなデバッガにはかなり慣れていますが、ここで起こっているすべてのことを見る方法を理解することはできません。

答えて

2

関数の引数の値と返される値を出力する場合は、元の関数をラップするラッパーを使用し、渡された値をfuncまたはmy_keyに出力し、その戻り値を出力できます。

def debug_func(func): 
    @functools.wraps(func) 
    def wrapper(*a, **kw): 
     print('Arguments', a, kw) 
     rv = func(*a, **kw) 
     print('Return value', repr(rv)) 
     return rv 
    return wrapper 

ような何か使用例:

>>> list(map(debug_func(len), ['foo', 'bar', 'foobar'])) 
Arguments ('foo',) {} 
Return value 3 
Arguments ('bar',) {} 
Return value 3 
Arguments ('foobar',) {} 
Return value 6 
[3, 3, 6] 

それとも

>>> min(['foo', 'bar', 'foobar'], keydebug_func(len)) 
Arguments ('foo',) {} 
Return value 3 
Arguments ('bar',) {} 
Return value 3 
Arguments ('foobar',) {} 
Return value 6 
'foo' 

同様のアプローチがあまりにもイテレータのために使用することができます。

def debug_iter(iterator): 
    while True: 
     value = next(iterator) 
     print('Iterator yielded', repr(value)) 
     yield value 

は使用方法:

>>> [i for i in debug_iter(i ** 2 for i in range(5)) if i % 2] 
Iterator yielded 0 
Iterator yielded 1 
Iterator yielded 4 
Iterator yielded 9 
Iterator yielded 16 
[1, 9] 
関連する問題