38

Possible Duplicate:
Static class variables in Python
What is the Python equivalent of static variables inside a function?

How can I use static fields in Python ?

for example i want to count how many times the function has been called - how can i do this ?

asked Nov 13, 2011 at 12:33
10
  • @PaulManta: I disagree. Your link is not related to class static fields (as OP says), but to " the static member at the function level, as opposed to the class level ", as stated by OP within the question you gave use link to. Commented Nov 13, 2011 at 14:11
  • 2
    @Tadeck The word 'class' doesn't even appear in the question... But the phrase 'static member of a function' does. Commented Nov 13, 2011 at 16:49
  • @PaulManta: Please read the question you linked to again - there are both words: " class " and " function ". In the current question (this question) there is a reference to " static fields ". Because of that, and because I have never heard of " static fields " in reference to static variables within function, but I have heard of " static fields " in reference to static member variables of a class, I assumed the current question is about static member variables of a class. Unless you will prove otherwise, I suppose the upvotes of my first comment mean some support in this matter. Commented Nov 13, 2011 at 17:47
  • @Tadeck Regarding votes: Good for you, here are two internet credits. Seriously, what's the argument about? The example is clear, he wants to know how to count how many times a function was called. In lack of a better term he used the rather incorrect 'static fields', but his intention is still clear from the example and title. Where's the problem? Commented Nov 13, 2011 at 21:01
  • @Tadeck The word 'class' appears in this context, 'how does one implement the static member at the function level, as opposed to the class level'. Lol at you making such a big deal out of this. Commented Nov 13, 2011 at 21:03

4 Answers 4

9

If you wish to count how many times a method has been called, no matter which instance called it, you could use a class member like this:

class Foo(object):
 calls=0 # <--- call is a class member
 def baz(self):
 Foo.calls+=1
foo=Foo()
bar=Foo()
for i in range(100): 
 foo.baz()
 bar.baz()
print('Foo.baz was called {n} times'.format(n=foo.calls))
# Foo.baz was called 200 times

When you define calls this way:

class Foo(object):
 calls=0 

Python places the key-value pair ('calls', 0) in Foo.__dict__.

It can be accessed with Foo.calls. Instances of Foo, such as foo=Foo(), can access it with foo.calls as well.

To assign new values to Foo.calls you must use Foo.calls = .... Instances can not use foo.calls = ... because that causes Python to place a new and different key-value pair in foo.__dict__, where instance members are kept.

answered Nov 13, 2011 at 12:36
Sign up to request clarification or add additional context in comments.

Comments

5

Here's a decorator adding counting to a function.

import functools
def count_calls(func):
 @functools.wraps(func)
 def decor(*args, **kwargs):
 decor.count += 1
 return func(*args, **kwargs)
 decor.count = 0
 return decor

Usage:

>>> @count_calls
... def foo():
... pass
...
>>> foo.count
0
>>> foo()
>>> foo.count
1
answered Nov 13, 2011 at 13:56

3 Comments

the decorator might be better called count_calls
It's quite the most complicated way of doing it, isn't it ?
@Patryk: Not at all; defining a decorator means you can count calls on any number of functions by adding a single line prefixing the function definition. Using the class attribute to count calls to a method doesn't generalize like that (it could, but it would end up equivalent to the decorator solution, more verbose, and likely somewhat slower).
4

Here is some example counting the number of calls of all objects of the same class:

class Swallow():
 i = 0 # will be used for counting calls of fly()
 def fly(self):
 Swallow.i += 1

And this is the proof:

>>> a = Swallow()
>>> b = Swallow()
>>> a.fly()
>>> a.i
1
>>> Swallow.i
1
>>> b.fly()
>>> b.i
2
>>> Swallow.i
2

so you can read it by giving the object name or class name.

answered Nov 13, 2011 at 12:39

Comments

2

Here's one simplistic way to do it:

def func():
 if not hasattr(func, 'counter'):
 func.counter = 0
 func.counter += 1
 counter = 0 # Not the same as `func.counter`
 print(func.counter)

Or if you don't like the if being executed on every call, you can do:

def func():
 func.counter += 1
 print(func.counter)
func.counter = 0
answered Nov 13, 2011 at 14:04

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.