Python有像Perl 5.10的“状态”变量吗?

时间:2009-03-03 00:17:48

标签: python perl

在Perl 5.10中,我可以说:

sub foo () {
  state $x = 1;
  say $x++;
}

foo();
foo();
foo();

...它会打印出来:

1
2
3

Python有这样的东西吗?

11 个答案:

答案 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有一些类似的生成器:

What does the "yield" keyword do in 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()

输出仅为12,而不是101102

答案 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)

最好的方法是使用classgeneratoryield)。

为了完整起见,这里是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
>>> 
"""