samuelcolvin / python-devtools

Dev tools for python
https://python-devtools.helpmanual.io/
MIT License
985 stars 47 forks source link

added f_timer decorator #42

Closed ChrisPappalardo closed 5 years ago

ChrisPappalardo commented 5 years ago

I added f_timer, a decorator function that wraps a function or method call with an instance of your Timer class for easy use of Timer in development. I also added a unit test and updated your documentation for f_timer.

FYI, I noticed that the unit tests would sporadically fail due to slight variances in the timing (inside a Docker container). Consider updating your regex to look more like f_timer_test.

codecov[bot] commented 5 years ago

Codecov Report

Merging #42 into master will not change coverage. The diff coverage is 100%.

@@          Coverage Diff          @@
##           master    #42   +/-   ##
=====================================
  Coverage     100%   100%           
=====================================
  Files           6      6           
  Lines         499    510   +11     
  Branches       79     79           
=====================================
+ Hits          499    510   +11
samuelcolvin commented 5 years ago

how about using the normal timer function but detecting that the first argument (I guess to Timer.__call__) is a function?

ChrisPappalardo commented 5 years ago

I've never implemented a decorator that way. It seems possible, but complicated (and a bit slow and messy as it relies on inspect): https://stackoverflow.com/questions/52191968/check-if-a-function-was-called-as-a-decorator If you'd rather go in this direction, it probably makes more sense to close out the PR and start from scratch.

samuelcolvin commented 5 years ago

should be pretty simple, something like

class Timer:
    def __call__(self, function):
        if callable(function):
            def f_wrapper(*args, **kwargs):
                print('function wrapped')
                return function(*args, **kwargs)
            return f_wrapper
        print('not a callable')

def timer(foo=1, bar=2):
    return Timer()

@timer()
def foobar(a, b, c):
    return a + b + c

print(foobar(1, 2, 3))

You also need to take care of the case that timer is called "bare" eg.

@timer
def foobar(a, b, c):
    return a + b + c

But that's pretty easy too.