Python 2.7-使用类作为装饰器进行计时和记忆

时间:2018-08-17 20:27:23

标签: python-2.7 decorator python-decorators memoization

我对Python完全陌生,我目前正在一个项目中,我有一个Timer和Memoize类,这两个类都应该具有用作装饰器的能力,并且可以使用具有许多参数的函数。

问题

我当前的问题是我试图将它们都用作函数的装饰器。但是,仅在函数的第一次调用而不是第二次调用Timer。例如,使用以下代码:

# Import the Memoize class from the memoization module
from memoization import Memoize


# Import the time module
import time


# Import the logging module
import logging


# Import the Timer class from the timer module
from timer import Timer


@Memoize
@Timer
def pass_and_square_time(seconds):
    # Call time.sleep(seconds)
    time.sleep(seconds)
    # Return the square of the input seconds amount.
    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):

<function pass_and_square_time at 0x02B9A870> 30.003000021 seconds

    The initial call of pass_and_square_time(30) yields: 900

    The second call of pass_and_square_time(30) yields: 900

当我希望它也返回第二个电话上方的秒数(因为那是第二个时间。初始电话上方的时间就是初始电话的时间)。我相信@Memoize装饰器在第二个调用上正常工作,因为它最初在第一个调用之后显示,而不是执行time.sleep(30)调用。


计时器

我的Timer类的实现如下:

class Timer(object):
    def __init__(self, fcn, timer_name='Timer'):
        self._start_time = None
        self._last_timer_result = None
        self._display = 'seconds'
        self._fcn = fcn
        self._timer_name = timer_name
        self.__wrapped__ = self._fcn

    def __call__(self, *args):
        self.start()
        fcn_res = self._fcn(*args)
        self.end()
        print '\n{func} {time} seconds'.format(func=self._fcn, time=self.last_timer_result)
        return fcn_res

    '''
    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类的实现如下:

class Memoize(object):
    def __init__(self, fcn):
        self._fcn = fcn
        self._memo = {}
    self.__wrapped__ = self.__call__

def __call__(self, *args):
    if args not in self._memo:
        self._memo[args] = self._fcn(*args)

    return self._memo[args]

使用的参考

我查看过并试图为我的课程建模的参考文献是:

Python类装饰器

Python记忆化


感谢您的阅读和提供的任何帮助!

1 个答案:

答案 0 :(得分:0)

使用代码,您正在记住一个定时函数,这意味着当在缓存中找到参数时,也会跳过定时代​​码。如果您反转装饰器的顺序

@Timer
@Memoize
def pass_and_square_time(seconds):
    # Call time.sleep(seconds)
    time.sleep(seconds)
    # Return the square of the input seconds amount.
    return seconds**2

现在您正在计时记忆功能。不管是否在缓存中找到参数,您都可以将调用时间记入已记忆的函数中。