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 constructorHere is an example of the class being used:
from foo import foo for i in range(0, 5): foo() # function callThe output printed to the console is:
counter is 1 counter is 2 counter is 3 counter is 4 counter is 5If 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, 9View Discussion
Improve Article
Save Article
View Discussion
Improve Article
Save Article
All objects share class or static variables. An instance or non-static variables are different for different objects (every object has a copy). For example, let a Computer Science Student be represented by a class CSStudent. The class may have a static variable whose value is “cse” for all objects. And class may also have non-static members like name and roll.
In C++ and Java, we can use static keywords to make a variable a class variable. The variables which don’t have a preceding static keyword are instance variables. See this for the Java example and this for the C++ example.
Features of Static Variables
- Static variables are allocated memory ones when the object for the class is created for the first time.
- Static variables are created outside of methods but inside a class
- Static variables can be accessed through a class but not directly with a instance.
- Static variables behavior doesn’t change for every object.
The Python approach is simple; it doesn’t require a static keyword.
Note: All variables which are assigned a value in the class declaration are class variables. And variables that are assigned values inside methods are instance variables.
Example:
Python
class CSStudent:
stream = 'cse'
def __init__(self,name,roll):
self.name = name
self.roll = roll
a = CSStudent('Geek', 1)
b = CSStudent('Nerd', 2)
print(a.stream)
print(b.stream)
print(a.name)
print(b.name)
print(a.roll)
print(b.roll)
print(CSStudent.stream)
a.stream = 'ece'
print(a.stream)
print(b.stream)
CSStudent.stream = 'mech'
print(a.stream)
print(b.stream)
Output:
cse cse Geek Nerd 1 2 cse ece cse ece mech