这个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
其他答案已经展示了你应该这样做的方式。这里有一个你不应该做的方法。
>>> def foo(counter=[0]):
... counter[0] += 1
... print("Counter is %i." % counter[0]);
...
>>> foo()
Counter is 1.
>>> foo()
Counter is 2.
>>>
默认值只有在函数第一次被评估时才会被初始化,而不是每次执行时都会被初始化,所以你可以使用列表或任何其他可变对象来存储静态值。
使用生成器函数来生成一个迭代器。
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语句的文档。