What is the Python equivalent of static variables inside a function?
What is the idiomatic Python equivalent of this C/C++ code?
void foo()
{
static int counter = 0;
counter++;
printf("counter is %dn", counter);
}
specifically, how does one implement the static member at the function level, as opposed to the class level? And does placing the function into a class change anything?
A bit reversed, but this should work:
def foo():
foo.counter += 1
print "Counter is %d" % foo.counter
foo.counter = 0
If you want the counter initialization code at the top instead of the bottom, you can create a decorator:
def static_var(varname, value):
def decorate(func):
setattr(func, varname, value)
return func
return decorate
Then use the code like this:
@static_var("counter", 0)
def foo():
foo.counter += 1
print "Counter is %d" % foo.counter
It'll still require you to use the foo.
prefix, unfortunately.
EDIT (thanks to ony): This looks even nicer:
def static_vars(**kwargs):
def decorate(func):
for k in kwargs:
setattr(func, k, kwargs[k])
return func
return decorate
@static_vars(counter=0)
def foo():
foo.counter += 1
print "Counter is %d" % foo.counter
You can add attributes to a function, and use it as a static variable.
def myfunc():
myfunc.counter += 1
print myfunc.counter
# attribute must be initialized
myfunc.counter = 0
Alternatively, if you don't want to setup the variable outside the function, you can use hasattr()
to avoid an AttributeError
exception:
def myfunc():
if not hasattr(myfunc, "counter"):
myfunc.counter = 0 # it doesn't exist yet, so initialize it
myfunc.counter += 1
Anyway static variables are rather rare, and you should find a better place for this variable, most likely inside a class.
One could also consider:
def foo():
try:
foo.counter += 1
except AttributeError:
foo.counter = 1
Reasoning:
ask for forgiveness not permission
) if
branch (think StopIteration exception)