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

824 投票
31 回答
489850 浏览
提问于 2025-04-11 18:03

这段话在问,Python中有没有和这段C/C++代码等价的写法?

void foo()
{
    static int counter = 0;
    counter++;
    printf("counter is %d\n", counter);
}

具体来说,怎么在函数级别实现静态成员,而不是在类级别?把这个函数放到一个类里面会有什么变化吗?

31 个回答

266

你还可以考虑:

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

理由:

  • 更符合Python的风格(“先做再说,不要问”)
  • 使用异常(只抛出一次)来代替if判断(可以想想StopIteration这个异常)
294

你可以给一个函数添加属性,这样就能把它当作静态变量来用。

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

# attribute must be initialized
myfunc.counter = 0

另外,如果你不想在函数外面设置这个变量,可以使用 hasattr() 来避免出现 AttributeError 错误:

def myfunc():
  if not hasattr(myfunc, "counter"):
     myfunc.counter = 0  # it doesn't exist yet, so initialize it
  myfunc.counter += 1

不过,静态变量其实很少用,通常你应该把这个变量放在更合适的地方,最有可能是在一个类里面。

867

有点反过来了,不过这样应该可以工作:

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

如果你想把计数器的初始化代码放在最上面,而不是下面,你可以创建一个装饰器:

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

不过,你还是需要用 foo. 这个前缀,真是麻烦。

(感谢: @ony)

撰写回答