Archive for June 27th, 2009

Filed Under (Python) by Marcin Kuźmiński on June-27-2009

UPDATE: i added two small fixes. When a functions is returning let’s pass the return value further, and exception when there’s no parameters.

I began studying more about decorators. I made a simple one for now it can be used to calculate execution time in miliseconds,seconds,minutes or hours of function decorated. It uses closures with wrapper function for handling parameters. Next time i’ll post decorator for running a function in a background using threads.

Here’s the code:

''' @author: marcink '''

import time
from types import FunctionType

class GetExecutionTime:
    '''
    This generic class is meant to be used as decorator for messuring
    simple method execution time it works on class methods as well
    as regular non class functions ;
    Availible parameters:
        'ms' - miliseconds
        's' - seconds
        'm' - minutes
        'h' - hours
    usage: @GetExecutionTime(param)

    samples:
    @GetExecutionTime('s')
    def samplemethod(self,params):
        function body
    will print executions time at end in seconds

    @GetExecutionTime('m')
    def samplemethod(params):
        function body
    will print executions time at end in minutes

     '''

    def __init__(self, *args):
        #in case of calling without parametrs
        #first argument will be the function decorated raise exception than

        if len(args) is 0 or type(args[0]) is FunctionType:
            raise Exception("Calling decorator without parameters is not possible")
        else:
            self.fn = None
            self.d_as = args[0]

        def miliseconds():return 1
        def seconds(): return 10000000000
        def minutes():return seconds() * 60
        def hours(): return minutes() * 60
        def default_():return seconds()

        #this is a cool way to replace switch case with default parameter
        commands = {'ms':miliseconds,
                    's':seconds,
                    'm':minutes,
                    'h':hours}
        self.display_as = commands.get(self.d_as, default_)()

    def __call__(self,fn):

        display_as = self.display_as
        d_as = self.d_as

        def wrapper_function(*args, **kwargs):
            start = time.time()

            ret = fn(*args,**kwargs)

            end = time.time()
            microsec = (end - start) * 10000000000

            print "function %s execution time: %s %s" % (fn.__name__, (microsec) / display_as, d_as)
            if ret:
                return ret
        return wrapper_function

#EXAMPLES:

from time import sleep

@GetExecutionTime('s')
def short_func(max, min):
    for x in range(3):
        sleep(1)
    print max,min
    return (max, min)

short_func(100, 10)

''' prints: function short_func execution time: 3.00342392921 s '''