1

I am trying to write a Python decorator that will store the time that a function took to run in an instance attribute.

Code:

from functools import wraps
import time


def time_func(func):
    """ Decorator to log the time func takes to run."""
    @wraps(func)
    def _dec(self, *args, **kwargs):
        if not hasattr(self, '__func_times'):
            self.__func_times = {}
        t0 = time.time()
        ret = func(self, *args, **kwargs)
        t1 = time.time()
        self.__func_times[func.__name__] = (t1 - t0)
        return ret
    return _dec


class Foo(object):

    def __init__(self):
        self.__func_times = {}

    @time_func
    def f1(self):
        sleep_time = 1
        print "f1 sleeping {} sec".format(sleep_time)
        time.sleep(sleep_time)

    def f1_time(self):
        print "inside _last_func_time:{}".format(self.__func_times.get('f1'))
        print "__func_times: {}".format(self.__func_times)
        return self.__func_times.get('f1')

When I run the f() method, I can immediately see that the __func_times dict has the value that the decorator set.

>>> f = Foo()
>>> f.f1()
f1 sleeping 1 sec
>>> f.__func_times
{'f1': 1.0000121593475342}

But when I run the f1_times() method, it sees the dictionary as empty and doesn't return anything.

>>> print f.f1_time()
inside _last_func_time: None
__func_times: {}
None
>>>

What is going wrong?

zoidberg
  • 1,969
  • 4
  • 22
  • 33
  • 1
    You're using double-leading-underscore names. You were probably told those indicate private variables. That isn't quite correct, but still, why are you trying to access private variables from your decorator, which is defined outside the class and shouldn't have access to the class's private variables? – user2357112 Mar 24 '17 at 23:12
  • Changing to single underscore fixed it. Thank you. I only used the double underscore to try and avoid any other class that might use that variable name. – zoidberg Mar 24 '17 at 23:42

0 Answers0