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 write int x = square[5];
even if square
is an object [with
overloaded operator[]
] and not technically not a "function." You can give a function-object any of the features that you could give a class object.
# C++ function object
class Foo_class {
private:
int counter;
public:
Foo_class[] {
counter = 0;
}
void operator[] [] {
counter++;
printf["counter is %d\n", counter];
}
};
Foo_class foo;
In Python, we can also overload operator[]
except that the method is instead named __call__
:
Here is a class definition:
class Foo_class:
def __init__[self]: # __init__ is similair to a C++ class constructor
self.counter = 0
# self.counter is like a static member
# variable of a function named "foo"
def __call__[self]: # overload operator[]
self.counter += 1
print["counter is %d" % self.counter];
foo = Foo_class[] # call the constructor
Here is an example of the class being used:
from foo import foo
for i in range[0, 5]:
foo[] # function call
The output printed to the console is:
counter is 1
counter is 2
counter is 3
counter is 4
counter is 5
If you want your function to take input arguments, you can add those to __call__
as well:
# FILE: foo.py - - - - - - - - - - - - - - - - - - - - - - - - -
class Foo_class:
def __init__[self]:
self.counter = 0
def __call__[self, x, y, z]: # overload operator[]
self.counter += 1
print["counter is %d" % self.counter];
print["x, y, z, are %d, %d, %d" % [x, y, z]];
foo = Foo_class[] # call the constructor
# FILE: main.py - - - - - - - - - - - - - - - - - - - - - - - - - - - -
from foo import foo
for i in range[0, 5]:
foo[7, 8, 9] # function call
# Console Output - - - - - - - - - - - - - - - - - - - - - - - - - -
counter is 1
x, y, z, are 7, 8, 9
counter is 2
x, y, z, are 7, 8, 9
counter is 3
x, y, z, are 7, 8, 9
counter is 4
x, y, z, are 7, 8, 9
counter is 5
x, y, z, are 7, 8, 9
You can make static variables inside a function in many ways in Python. If declaring a static variable in a function means variable throughout the lifetime of the program.
Simple 3 example code for it:-
Add attributes to a function
You can add attributes to a function, and use it as a static variable. Count how many times functions have been called using a static variable.
def foo[]:
foo.counter += 1
print["Counter is %d" % foo.counter]
foo.counter = 0
foo[]
foo[]
Output:
Initialization code at the top using decorator
If you want the counter initialization code at the top instead of the bottom, you can create a decorator:
def static_vars[**kwargs]:
def decorate[func]:
for k in kwargs:
setattr[func, k, kwargs[k]]
return func
return decorate
# Then use the code like this:
@static_vars[counter=0]
def foo[]:
foo.counter += 1
print["Counter is %d" % foo.counter]
foo[]
Output: Counter is 1
Use hasattr[]
Alternatively, if you don’t want to set up 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
return myfunc.counter
print[myfunc[]]
print[myfunc[]]
Output:
1
2
Do comment if you have any doubts or suggestions on this Python variable topic.
Note: IDE: PyCharm 2021.3.3 [Community Edition]
Windows 10
Python 3.10.1
All Python Examples are in Python 3, so Maybe its different from python 2 or upgraded versions.
Degree in Computer Science and Engineer: App Developer and has multiple Programming languages experience. Enthusiasm for technology & like learning technical.