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

这个C/C++代码的Python成语等价物是什么?

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

具体来说,如何在函数层实现静态成员,而不是在类层?把函数放在类中会有什么变化吗?

解决办法

有点颠倒,但这应该可以。

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

如果你希望计数器的初始化代码在顶部而不是底部,你可以创建一个装饰器。

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

然后像这样使用代码。

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

不幸的是,它仍然需要你使用foo.前缀。


编辑(感谢[ony](https://stackoverflow.com/questions/279561/what-is-the-python-equivalent-of-static-variables-inside-a-function/279586#comment41067162_279586))。这看起来更漂亮了

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
评论(24)

其他答案已经展示了你应该这样做的方式。这里有一个你不应该做的方法。

>>> def foo(counter=[0]):
...   counter[0] += 1
...   print("Counter is %i." % counter[0]);
... 
>>> foo()
Counter is 1.
>>> foo()
Counter is 2.
>>> 

默认值只有在函数第一次被评估时才会被初始化,而不是每次执行时都会被初始化,所以你可以使用列表或任何其他可变对象来存储静态值。

评论(9)

使用生成器函数来生成一个迭代器。

def foo_gen():
    n = 0
    while True:
        n+=1
        yield n

然后使用它,就像

foo = foo_gen().next
for i in range(0,10):
    print foo()

如果你想要一个上限。

def foo_gen(limit=100000):
    n = 0
    while n < limit:
       n+=1
       yield n

如果迭代器终止了(如上面的例子),你也可以直接在它上面循环,如

for i in foo_gen(20):
    print i

当然,在这些简单的情况下,最好是使用xrange :)

这里是关于yield语句的文档。

评论(0)