2
私はコルーチンまたは関数をラップするデコレータを作ろうとしています。コルーチンまたは関数のいずれかをラップすることができるPythonデコレータを作成するには?
私が試した最初のものは、ラッパーで、単純な重複コードだった:
def duration(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
start_ts = time.time()
result = func(*args, **kwargs)
dur = time.time() - start_ts
print('{} took {:.2} seconds'.format(func.__name__, dur))
return result
@functools.wraps(func)
async def async_wrapper(*args, **kwargs):
start_ts = time.time()
result = await func(*args, **kwargs)
dur = time.time() - start_ts
print('{} took {:.2} seconds'.format(func.__name__, dur))
return result
if asyncio.iscoroutinefunction(func):
return async_wrapper
else:
return wrapper
これは動作しますが、この2つの別々のデコレータを書くよりもはるかに良いではないと私は、コードの重複を避けたいです。
その後、私はクラスを使用してデコレータを作ってみました:を試してみてください、私のために非常によく、いくつかのケースで動作することを
class SyncAsyncDuration:
def __init__(self):
self.start_ts = None
def __call__(self, func):
@functools.wraps(func)
def sync_wrapper(*args, **kwargs):
self.setup(func, args, kwargs)
result = func(*args, **kwargs)
self.teardown(func, args, kwargs)
return result
@functools.wraps(func)
async def async_wrapper(*args, **kwargs):
self.setup(func, args, kwargs)
result = await func(*args, **kwargs)
self.teardown(func, args, kwargs)
return result
if asyncio.iscoroutinefunction(func):
return async_wrapper
else:
return sync_wrapper
def setup(self, func, args, kwargs):
self.start_ts = time.time()
def teardown(self, func, args, kwargs):
dur = time.time() - self.start_ts
print('{} took {:.2} seconds'.format(func.__name__, dur))
が、このソリューションでは、私はまたはとで関数を置くことができませんステートメント。 コードを複製せずにデコレータを作成する方法はありますか?
どうもありがとう、それは正確に何をされます私は探していた。 –