What is the idiomatic Python equivalent of this C/C++ code?
void foo()
{
static int counter = 0;
counter++;
Here is a fully encapsulated version that doesn't require an external initialization call:
def fn():
fn.counter=vars(fn).setdefault('counter',-1)
fn.counter+=1
print (fn.counter)
In Python, functions are objects and we can simply add, or monkey patch, member variables to them via the special attribute __dict__. The built-in vars() returns the special attribute __dict__.
EDIT: Note, unlike the alternative try:except AttributeError answer, with this approach the variable will always be ready for the code logic following initialization. I think the try:except AttributeError alternative to the following will be less DRY and/or have awkward flow:
def Fibonacci(n):
if n<2: return n
Fibonacci.memo=vars(Fibonacci).setdefault('memo',{}) # use static variable to hold a results cache
return Fibonacci.memo.setdefault(n,Fibonacci(n-1)+Fibonacci(n-2)) # lookup result in cache, if not available then calculate and store it
EDIT2: I only recommend the above approach when the function will be called from multiple locations. If instead the function is only called in one place, it's better to use nonlocal:
def TheOnlyPlaceStaticFunctionIsCalled():
memo={}
def Fibonacci(n):
nonlocal memo # required in Python3. Python2 can see memo
if n<2: return n
return memo.setdefault(n,Fibonacci(n-1)+Fibonacci(n-2))
...
print (Fibonacci(200))
...