I'm completely new to Python and I'm currently working on a project where I have a Timer and Memoize class, both of which should have the ability to be used as decorators and can work with functions with any number of parameters.
Problem
My current problem is that I am trying to use both of them as decorators on a function; however, the Timer is only called on the first call of the function and not the second. For instance, using this code:
# 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))
returns the following:
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
when I want it to return the seconds above that second call as well (Since that'd be the time of the second. The time above the initial call is the initial call's time). I believe that the @Memoize decorator is working properly on that second call since it shows up pretty much initially after the first rather than performing the time.sleep(30) call.
Timer
My Timer class is implemented as follows:
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
My Memoize class is implemented as follows:
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]
References Used
The references I looked at and tried to model my classes off or are:
Python Class Decorators
- https://krzysztofzuraw.com/blog/2016/python-class-decorators.html
- Using classes as method decorators
- Python decorator best practice, using a class vs a function
Python Memoization
Thank You for Reading and for Any Help You Can Provide!