这是我的方法,但是我觉得这不是很简单,还有更好的方法吗?
import asyncio
import time
def timer_all(f):
if asyncio.iscoroutinefunction(f):
async def wrapper(*args, **kwargs):
now = time.time()
result = await f(*args, **kwargs)
print('used {}'.format(time.time() - now))
return result
else:
def wrapper(*args, **kwargs):
now = time.time()
result = f(*args, **kwargs)
print('used {}'.format(time.time() - now))
return result
return wrapper
有很多装饰器,重试,添加日志等,都将以这种方式编写,有点难看,对吧?
答案 0 :(得分:1)
尽管在专门的装饰器中重复相同的代码并没有真正的问题。 这就是我将如何进行重构的方法。
我将使用一个类装饰器,该装饰器保持接受预调用功能和后调用功能, 两者都将用装饰器的实例调用。 调用前功能的结果将保存到装饰器的属性中。
这对于需要计算增量的特殊计时情况是必需的。
我猜可能还有其他一些示例,可能需要调用函数执行前的返回值。
我还将保存执行的装饰函数的结果保存到装饰器实例的result属性中。这使post call函数可以读取该值以进行记录。
这是一个示例实现:
import asyncio
class WrapAll(object):
def __init__(self, pre=lambda _: None, post=lambda _: None):
self.pre = lambda : pre(self)
self.pre_val = None
self.result = None
self.post = lambda : post(self)
def __call__(self, fn):
if asyncio.iscoroutinefunction(fn):
async def wrap(*args, **kwargs):
self.pre_val = self.pre()
self.result = await fn(*args, *kwargs)
self.post()
return self.result
else:
def wrap(*args, **kwargs):
self.pre_val = self.pre()
self.result = fn(*args, *kwargs)
self.post()
return self.result
return wrap
import asyncio
import time
timer = dict(
pre=lambda self: time.time(),
post=lambda self: print('used {}'.format(time.time()-self.pre_val))
)
@WrapAll(**timer)
def add(x, y):
return x + y
@WrapAll(**timer)
async def async_add(x, y):
future = asyncio.Future()
future.set_result(x+y)
await future
return future.result()
运行同步加法器
>>> add(3, 4)
used 4.76837158203125e-06
7
运行异步加法器
>>> loop = asyncio.get_event_loop()
>>> task = asyncio.ensure_future(async_add(3, 4))
>>> try:
... loop.run_until_complete(task)
... except RuntimeError:
... pass
used 2.193450927734375e-05
import asyncio
import logging
FORMAT = '%(message)s'
logging.basicConfig(format=FORMAT)
logger = dict(
post=lambda self: logging.warning('subtracting {}'.format(self.result))
)
@WrapAll(**logger)
def sub(x, y):
return x - y
@WrapAll(**logger)
async def async_sub(x, y):
future = asyncio.Future()
future.set_result(x-y)
await future
return future.result()
运行同步减法器:
>>> sub(5, 6)
subtracting -1
运行异步减法器:
>>> loop = asyncio.get_event_loop()
>>> task = asyncio.ensure_future(async_sub(5, 6))
>>> try:
... loop.run_until_complete(task)
... except RuntimeError:
... pass
subtracting -1