在 Perl 5.10 中,我可以这样说:
Python有类似这样的东西吗?
sub foo () {
state $x = 1;
say $x++;
}
foo();
foo();
foo();
...并且它将打印出:
1
2
3
Python有类似这样的东西吗?
在这种情况下,使用类可能更加合适(通常在涉及"状态"的任何事情上都更加合适):
class Stateful(object):
def __init__(self):
self.state_var = 0
def __call__(self):
self.state_var = self.state_var + 1
print self.state_var
foo = Stateful()
foo()
foo()
最接近的类比可能是将值附加到函数本身。
def foo():
foo.bar = foo.bar + 1
foo.bar = 0
foo()
foo()
foo()
print foo.bar # prints 3
如果您不确定这是否是您要寻找的,那么Python具有生成器函数,它们不会直接返回值,而是生成一个生成器对象,每次生成一个新值。
def gen():
x = 10
while True:
yield x
x += 1
用法:
>>> a = gen()
>>> a.next()
10
>>> a.next()
11
>>> a.next()
12
>>> a.next()
13
>>>
点击这里了解更多关于yield的解释:
Python中的“yield”关键字是什么意思?
以下是在Python中实现闭包的一种方法:
def outer():
a = [4]
def inner():
print a[0]
a[0] = a[0] + 1
return inner
fn = outer()
fn() # => 4
fn() # => 5
fn() # => 6
我直接从一篇Python邮件列表的帖子中借鉴了这个例子。
是的,不过您必须在foo
中使用前先声明全局变量:
x = 0
def foo():
global x
x += 1
print x
foo()
foo()
foo()
编辑:回应评论,确实python没有函数内部的静态变量。需要注意的是,这个例子中的x
只对模块的其余部分公开为全局变量。例如,假设上面的代码在test.py
中。现在假设你编写了以下模块:
from test import foo
x = 100
foo()
foo()
输出结果只会是1
和2
,而不是101
和102
。
def static_num2():
k = 0
while True:
k += 1
yield k
static = static_num2().next
for i in range(0,10) :
print static()
为避免全局变量。从此链接中提取有关相同问题的内容。
static= itertools.count().next
并删除static_num2
定义。 - tzot这里有另一种非常便宜的方法来实现它,它是Tryiptich答案的变体,但使用装饰器。
def static_var( name, value ):
def dec( function ):
setattr( function, name, value )
return function
return dec
@static_var( 'counter', 0 )
def counting_function():
counting_function.counter = counting_function.counter + 1
print counting_function.counter
"""
>>> counting_function()
1
>>> counting_function()
2
>>> counting_function()
3
>>> counting_function()
4
>>> counting_function()
5
>>>
"""