是否有规范的方法来修饰函数和协同程序?
def timed(func):
"""
A decorator for logging the execution time of each function decorated with it.
:param func: function to be wrapped
:return: a decorated function (in __debug__ mode) or the function is untouched.
"""
if not __debug__:
return func
name = func.__name__
logger = logging.getLogger("timer")
logger.addHandler(logging.StreamHandler())
logger.setLevel(logging.DEBUG)
is_coro = asyncio.iscoroutinefunction(func)
wrapper = asyncio.coroutine if is_coro else lambda f: f
@functools.wraps(func)
@wrapper
def wrapped(*args, **kwargs):
start = time.time()
try:
val = func(*args, **kwargs)
# if is_coro:
# yield from val
except Exception as e:
logger.debug("{} failed in {:.05}s".format(name, time.time() - start))
raise e
else:
logger.debug("{} ran in {:.05}s".format(name, time.time() - start))
return val
return wrapped
当然,注释掉的行会将wrapped
函数更改为生成器,无论asyncio.coroutine
是否用作装饰器。
除了将其分成两个不同的函数之外,还有更好的方法吗?
def timed(func):
"""
A decorator for logging the execution time of each function decorated with it.
:param func: function to be wrapped
:return: a decorated function (in __debug__ mode) or the function is untouched.
"""
if not __debug__:
return func
name = func.__name__
logger = logging.getLogger("timer")
logger.addHandler(logging.StreamHandler())
logger.setLevel(logging.DEBUG)
is_coro = asyncio.iscoroutinefunction(func)
@functools.wraps(func)
def wrapped(*args, **kwargs):
start = time.time()
try:
val = func(*args, **kwargs)
except Exception as e:
logger.debug("{} failed in {:.05}s".format(name, time.time() - start))
raise e
else:
logger.debug("{} ran in {:.05}s".format(name, time.time() - start))
return val
@functools.wraps(func)
async def wrapped_async(*args, **kwargs):
start = time.time()
try:
val = await func(*args, **kwargs)
except Exception as e:
logger.debug("{} failed in {:.05}s".format(name, time.time() - start))
raise e
else:
logger.debug("{} ran in {:.05}s".format(name, time.time() - start))
return val
return wrapped_async if is_coro else wrapped