简体   繁体   中英

Counting the number of function calls

So, I have a code snippet to count the number of function calls, and while browsing for potential optimal solutions, I came across a similar question posted here a few years ago:

is there a way to track the number of times a function is called?

One of the solutions listed in the thread above matched mine, but there was a subtle difference. When I posted my solution and asked about the potential pitfalls in my code, my comment was deleted even though mine was a solution to the question. So, I am hoping this one isn't closed as a duplicate, because frankly I don't know where to turn to.

Here was my solution:

def counter(func):
    counter.count=0
    def wrap(*args,**kwargs):
        counter.count += 1
        print "Number of times {} has been called so far 
            {}".format(func.__name__,counter.count)
        func(*args,**kwargs)
    return wrap

@counter
def temp(name):
    print "Calling {}".format(name)

My counter is defined as an attribute to the decorator 'counter', instead of the wrapper function 'wrap'. The code works as currently defined. But, is there a scenario where it may fail? Am I overlooking something here?

If you use this decorator on two separate functions, they'll share the same call count. That's not what you want. Also, every time this decorator is applied to a new function, it will reset the shared call count.

Aside from that, you've also forgotten to pass through the return value of func in wrap , and you can't stick an unescaped line break in the middle of a non-triple-quoted string literal like that.

With slight modification to your code you can make your counter decorator independent:

def counter(func, counter_dict={}):
    counter_dict[func]=0
    def wrap(*args,**kwargs):
        counter_dict[func] += 1
        print("Number of times {} has been called so far {}".format(func.__name__, counter_dict[func]))
        return func(*args,**kwargs)
    return wrap

@counter
def temp1(name):
    print("Calling temp1 {}".format(name))

@counter
def temp2(name):
    print("Calling temp2 {}".format(name))


temp1('1')
temp1('2')
temp2('3')

Prints:

Number of times temp1 has been called so far 1
Calling temp1 1
Number of times temp1 has been called so far 2
Calling temp1 2
Number of times temp2 has been called so far 1
Calling temp2 3

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM