What is the Python equivalent of static variables inside a function?

What is the idiomatic Python equivalent of this C/C++ code?

void foo()
{
    static int counter = 0;
    counter++;
    printf("counter is %dn", 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?


A bit reversed, but this should work:

def foo():
    foo.counter += 1
    print "Counter is %d" % foo.counter
foo.counter = 0

If you want the counter initialization code at the top instead of the bottom, you can create a decorator:

def static_var(varname, value):
    def decorate(func):
        setattr(func, varname, value)
        return func
    return decorate

Then use the code like this:

@static_var("counter", 0)
def foo():
    foo.counter += 1
    print "Counter is %d" % foo.counter

It'll still require you to use the foo. prefix, unfortunately.


EDIT (thanks to ony): This looks even nicer:

def static_vars(**kwargs):
    def decorate(func):
        for k in kwargs:
            setattr(func, k, kwargs[k])
        return func
    return decorate

@static_vars(counter=0)
def foo():
    foo.counter += 1
    print "Counter is %d" % foo.counter

You can add attributes to a function, and use it as a static variable.

def myfunc():
  myfunc.counter += 1
  print myfunc.counter

# attribute must be initialized
myfunc.counter = 0

Alternatively, if you don't want to setup 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

Anyway static variables are rather rare, and you should find a better place for this variable, most likely inside a class.


One could also consider:

def foo():
    try:
        foo.counter += 1
    except AttributeError:
        foo.counter = 1

Reasoning:

  • much pythonic ( ask for forgiveness not permission )
  • use exception (thrown only once) instead of if branch (think StopIteration exception)
  • 链接地址: http://www.djcxy.com/p/54160.html

    上一篇: 我应该放#! (shebang)在Python脚本中,它应该采用什么形式?

    下一篇: 什么是函数内部的静态变量的Python等价物?