Hello fellows...

Is there something like static function variables in python?
I know there are static attributes of a class, but what if i want
to use a static variable inside a function?
somthing like this (stupid) code in c++ for example:

int static_num()
{
     static int x = 0;
     return ++x;
}

void main()
{
     for (int i=0; i<10; i++)
     {
           cout << static_num() << endl;
     }
}

If there aren't such static variables , is there a way for doing something similar to this c++ code?

thanks a lot!

Dani AI

Generated

Python does not have C/C++-style static locals, but in modern Python the cleanest equivalent is a closure with a nonlocal binding so the state lives alongside the function and is not global.

def make_static_num(start=0):
    x = start
    def static_num():
        nonlocal x
        x += 1
        return x
    return static_num

static_num = make_static_num()
for _ in range(10):
    print(static_num())

Here, x persists across calls, scoped only to the returned function. This is explicit, testable, and avoids module-level globals. See the docs for nonlocal in the Python reference (The nonlocal statement). Note: if you share the same static_num instance across threads, wrap the increment with a lock to avoid races.

For pure counters, itertools.count is efficient and avoids manual bookkeeping:

from itertools import count

def make_counter(start=0):
    c = count(start + 1)
    def next_value():
        return next(c)
    return next_value

static_num = make_counter()
for _ in range(10):
    print(static_num())

This encapsulates state without globals or mutable default arguments. The iterator runs in O(1) per call and is part of the standard library (itertools.count).

Recommended Answers

All 9 Replies

x=0
def static_num() :
   global x
   x=x+1
   return x

for i in range(0,10) :
     print static_num

I always learn that the use of global variables is to be discouraged. Is this the only way to copy static variable behaviour in Python?

Bumsfeld you are right, avoid globals, they do lead to errors. Using a generator function avoids globals ...

def static_num2():
    k = 0
    while True:
       k += 1
       yield k

static = static_num2().next

for i in range(0,10) :
    print static()

I knew there had to be a way to avoid these global variables, I am still learning a lot, generator functions are somewhat confusing right now!

Hmm. There are a couple of ways you could simulate the effect of static variables - but they aren't explicitly in the language.

One way is to abuse the fact that default parameters for functions are evaluated only once when the function is defined, and then kept for the rest of time - so that if one makes the default value a new list or dictionary then it can be used to share values between any running version of the function. For example:

def last_argument(n, arg_store = []):
    "Return the argument used when the function was last called"
    arg_store.append(n)
    if len(arg_store) == 1:
        return -1
    else:
        return arg_store[-2]

I'm not sure whether this would be classed as a 'good solution' or not... I don't know whether it counts as confusing to use stored default arguments for sharing state - also you are never going to use this parameter.

As an alternative you could explicit give the function somewhere to store its state each time it's called. We could do this using an explicit paramter, a class or an instance.

For a parameter we'd effectively use the same as above, apart from we wouldn't specify a default value. We'd then call

state = []
last_argument(1, state)
last_argument(2, state)

The code for a class would use a class method for flair.

class A(object):
    last = -1
    @classmethod
    def last_argument(cls, n):
        temp = cls.last
        cls.last = n
        return temp

A.last_argument(1)
A.last_argument(17)...

The code an instance of a class is much as you would expect.

The default argument approach is probably the approach closest to a static variable, the class method might feel the 'cleanest' - depending on one's bigotries.

Tom

def egg(static={"count":0}):
    static["count"]+=1
    return static["count"]

print egg()
print egg()
# >>> 1
# >>> 2
commented: it's not a good idea for this question +0

python have static variables??????????

No it doesn't, but you can emulate static variables with default arguments, as shown above. This is a side effect of mutable types like dictionaries.

Hi,

You can use functions like this:

def static_num():
    static_num.x += 1
    return static_num.x
static_num.x = 0

if __name__ == '__main__':
    for i in range(10):
        print static_num()
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.