在Perl 5.10中,我可以说:
sub foo () {
state $x = 1;
say $x++;
}
foo();
foo();
foo();
...它会打印出来:
1
2
3
Python有这样的东西吗?
答案 0 :(得分:17)
一个类可能更适合这里(并且通常更适合涉及“州”的任何事情):
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()
答案 1 :(得分:12)
最接近的并行可能是将值附加到函数本身。
def foo():
foo.bar = foo.bar + 1
foo.bar = 0
foo()
foo()
foo()
print foo.bar # prints 3
答案 2 :(得分:9)
Python有一些类似的生成器:
答案 3 :(得分:8)
不确定这是否是您正在寻找的,但是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的更多说明:
What does the "yield" keyword do in Python?
答案 4 :(得分:5)
这是在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 mailing list post逐字借用了这个例子。
答案 5 :(得分:2)
是的,虽然您必须在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
。
答案 6 :(得分:2)
你也可以使用像
这样的东西def static_num2():
k = 0
while True:
k += 1
yield k
static = static_num2().next
for i in range(0,10) :
print static()
避免全局变量。从this link解除了同样的问题。
答案 7 :(得分:2)
不是我推荐这个,而是为了好玩:
def foo(var=[1]):
print var[0]
var[0] += 1
这是因为Python中的way mutable default arguments工作。
答案 8 :(得分:2)
最好的方法是使用class或generator(yield
)。
为了完整起见,这里是Python 3.x中的变量w / closure:
>>> def make_foo():
... x = 1
... def foo():
... nonlocal x
... print(x)
... x += 1
... return foo
...
>>> foo = make_foo()
>>> foo()
1
>>> foo()
2
>>> foo()
3
答案 9 :(得分:1)
>>> def foo():
x = 1
while True:
yield x
x += 1
>>> z = iter(foo())
>>> next(z)
1
>>> next(z)
2
>>> next(z)
3
答案 10 :(得分:0)
这是另一种肮脏的廉价方式,它是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
>>>
"""