我有一个计时器装饰器,在屏幕上打印“记忆装饰”功能所用的时间。但是,装饰器打印语句将备忘类作为功能名称打印在屏幕上,而不是输入要备忘的功能。例如,使用以下代码:
from memoization import Memoize
import time
import logging
from timer import Timer
@Timer
@Memoize
def pass_and_square_time(seconds):
time.sleep(seconds)
return seconds**2
def main():
logging.getLogger().setLevel(logging.ERROR)
print '\nFor pass_and_square_time({30}):'.format(n=num)
print '\n\tThe initial call of pass_and_square_time(30) yields: {ret}'.format(ret=pass_and_square_time(30))
print '\n\tThe second call of pass_and_square_time(30) yields: {ret}'.format(ret=pass_and_square_time(30))
返回以下内容:
For pass_and_square_time(30):
Timer Time Elapsed: 30.0 seconds
<memoization.Memoize object at 0x02E5BBD0> 30.0 seconds
The initial call of pass_and_square_time(30) yields: 900
Timer Time Elapsed: 0.0 seconds
<memoization.Memoize object at 0x02E5BBD0> 0.0 seconds
The second call of pass_and_square_time(30) yields: 900
当我想要该记忆时。该记忆为pass_and_square_time
。我尝试了self.__wrapper__
,functools.wraps
和functools.update_wrapper()
的各种不同组合,都无济于事。
我的Timer类的实现如下:
class Timer(object):
def __init__(self, fcn=None, timer_name='Timer'):
self._start_time = None
self._last_timer_result = None
self._display = 'seconds'
self._fcn = fcn
self._timer_name = timer_name
def __call__(self, *args):
self.start()
fcn_res = self._fcn(*args)
self.end()
print '\n\t{func} {time} seconds'.format(func=self._fcn, time=self.last_timer_result)
return fcn_res
def __get__(self, obj, objtype):
return partial(self.__call__, obj)
'''
start(), end(), and last_timer_result functions/properties implemented
below in order to set the start_time, set the end_time and calculate the
last_timer_result, and return the last_timer_result. I can include more
if you need it. I didn't include it just because I didn't want to make
the post too long
'''
我的Memoize类的实现如下:
from functools import update_wrapper, partial
class Memoize(object):
def __init__(self, fcn):
self._fcn = fcn
self._memo = {}
update_wrapper(self, fcn)
def __call__(self, *args):
if args not in self._memo:
self._memo[args] = self._fcn(*args)
return self._memo[args]
def __get__(self, obj, objtype):
return partial(self.__call__, obj)
答案 0 :(得分:0)
使用闭包比使用类要简单得多。
import functools
import time
def memoize(f):
_memo = {}
@functools.wraps(f)
def _(*args):
if args not in _memo:
_memo[args] = f(*args)
return _memo[args]
return _
我也将timer
写为
def timer(f):
@functools.wraps(f)
def _(*args):
start = time.time()
rv = f(*args)
end = time.time()
print '\n\t{func} {t} seconds'.format(func=f.__name__, t=end - start)
return rv
return _
然后
@timer
@memoize
def pass_and_square_time(seconds):
time.sleep(seconds)
return seconds**2
答案 1 :(得分:0)
RoundDown
和public static int RoundDown(this double dbl)
{
return Convert.ToInt32(Math.Floor(dbl));
}
都被实现为类,以这样的方式在装饰函数时它们返回自己的类的实例。因此,不能在返回的函数上使用Timer
或设置Memoize
(因为没有返回的函数)。
相反,我建议在functools.wrap
和__name__
上实现__repr__
,这将更好地表示修饰后的功能。当需要获取对象的字符串表示形式时,Python解释器将调用该函数。
这是当前情况和问题:
Timer
现在,如果您添加到Memoize
,则:
def pass_and_square_time(seconds):
time.sleep(seconds)
return seconds**2
print(pass_and_square_time) # <function pass_and_square_time at 0x00000000029A1620>
print(Memoize(pass_and_square_time)) # <Memoize object at 0x000000000295BDA0>
然后按预期工作:
Memoize
然后对class Memoize(object):
...
def __repr__(self):
return repr(self._fcn)
执行相同的操作,即使这样也可以:
print(pass_and_square_time) # <function pass_and_square_time at 0x00000000029A1620>
print(Memoize(pass_and_square_time)) # <function pass_and_square_time at 0x00000000029A1620>
请注意,Memoize
正是装饰者在这里所做的:
print(Timer(Memoize(pass_and_square_time))) # <function pass_and_square_time at 0x00000000029A1620>