What is the idiomatic Python equivalent of this C/C++ code?
void foo()
{
static int counter = 0;
counter++;
printf("counter is %d\n", 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?
One could also consider:
Reasoning:
ask for forgiveness not permission
)if
branch (think StopIteration exception)Sure this is an old question but I think I might provide some update.
It seems that the performance argument is obsolete. The same test suite appears to give similar results for siInt_try and isInt_re2. Of course results vary, but this is one session on my computer with python 3.4.4 on kernel 4.3.01 with Xeon W3550. I have run it several times and the results seem to be similar. I moved the global regex into function static, but the performance difference is negligible.
With performance issue out of the way, it seems that try/catch would produce the most future- and cornercase- proof code so maybe just wrap it in function
Using an attribute of a function as static variable has some potential drawbacks:
Idiomatic python for the second issue would probably be naming the variable with a leading underscore to signal that it is not meant to be accessed, while keeping it accessible after the fact.
An alternative would be a pattern using lexical closures, which are supported with the
nonlocal
keyword in python 3.Sadly I know no way to encapsulate this solution into a decorator.
Instead of creating a function having a static local variable, you can always create what is called a "function object" and give it a standard (non-static) member variable.
Since you gave an example written C++, I will first explain what a "function object" is in C++. A "function object" is simply any class with an overloaded
operator()
. Instances of the class will behave like functions. For example, you can writeint x = square(5);
even ifsquare
is an object (with overloadedoperator()
) and not technically not a "function." You can give a function-object any of the features that you could give a class object.In Python, we can also overload
operator()
except that the method is instead named__call__
:Here is a class definition:
Here is an example of the class being used:
The output printed to the console is:
If you want your function to take input arguments, you can add those to
__call__
as well:This answer shows that setdefault does not truly satisfy the OPs question of how to create static local variables.
It works as long as fn. is prefixed to each variable name. If you remove them like so:
there are no errors but counter is always 0 and that tells me the vars(fn) is NOT accessing local variables but rather a global, probably a decorator or attribute stash.
Had this worked it would have been my preferred solution. However since it doesn't, I'm inclined to go with a fully encapsulated class definition to create such static vars.
IMHO that is the most straightforward. Of course it depends on if you are more familiar with functional vs. OOP coding styles.
Many people have already suggested testing 'hasattr', but there's a simpler answer:
No try/except, no testing hasattr, just getattr with a default.