Pythonでジェネレータ関数に前処理,後処理を行うデコレータを適用したい
[環境]
+ OS Ubuntu 16.04
+ Python 3.5.2
Pythonで以下のようなデコレータを定義したとします。
def trace(f):
@functools.wraps(f)
def wrapper(*args, **kwargs):
print('Enter Func')
try:
ret = f(*args, **kwargs)
except:
print('EXCEPTION')
raise
print('Leave Func')
return ret
return wrapper
このデコレータは通常の関数であれば期待通り動作します。
def func():
print('Hello')
func = trace(func)
func()
<< Enter Func
<< Hello
<< Leave Func
しかし、ジェネレータ関数に対しては、期待通り動作しません。
def generator_func():
print('Start Generator')
for i in range(3):
yield(i)
generator_func = trace(generator_func)
for x in generator_func():
print(x)
<< Enter Func
<< Leave Func
<< Start Generator
<< 0
<< 1
<< 2
期待する出力は下記の通りです。このような出力を得るためのデコレータは定義可能でしょうか?
<< Enter Func
<< Start Generator
<< 0
<< 1
<< 2
<< Leave Func
その関数がgeneratorかどうかは下記のコードで判定できるようなので、ジェネレータ用にデコレータが工夫可能であれば、デコレータ内でジェネレータを判定して、分岐させようと考えています。
import inspect
inspect.isgeneratorfunction(func)