简体   繁体   English

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

[英]Does Python have something like Perl 5.10's “state” variables?

In Perl 5.10, I can say: 在Perl 5.10中,我可以说:

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

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

...and it will print out: ......它会打印出来:

1
2
3

Does Python have something like this? Python有这样的东西吗?

A class may be a better fit here (and is usually a better fit for anything involving "state"): 一个类可能更适合这里(并且通常更适合涉及“状态”的任何事情):

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()

The closest parallel is probably to attach values to the function itself. 最接近的并行可能是将值附加到函数本身。

def foo():
    foo.bar = foo.bar + 1

foo.bar = 0

foo()
foo()
foo()

print foo.bar # prints 3

Python has generators which do something similar: Python有一些类似的生成器:

What does the "yield" keyword do in Python? “yield”关键字在Python中的作用是什么?

Not sure if this is what you're looking for, but python has generator functions that don't return a value per se, but a generator object that generates a new value everytime 不确定这是否是您正在寻找的,但是python的生成器函数本身不返回值,而是每次都生成新值的生成器对象

def gen():
   x = 10
   while True:
      yield x
      x += 1

usage: 用法:

>>> a = gen()
>>> a.next()
10
>>> a.next()
11
>>> a.next()
12
>>> a.next()
13
>>> 

look here for more explanation on yield : 在这里查看有关产量的更多解释:
What does the "yield" keyword do in Python? “yield”关键字在Python中的作用是什么?

Here's one way to implement a closure in python: 这是在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

I borrowed this example verbatim from a python mailing list post . 我从python邮件列表帖子中逐字借用了这个例子。

Yes, though you have to declare your global variable first before it is encountered in foo : 是的,尽管在foo遇到全局变量之前必须首先声明它:

x = 0

def foo():
    global x
    x += 1
    print x

foo()
foo()
foo()

EDIT: In response to the comment, it's true that python has no static variables scoped within a function. 编辑:在回应评论时,python确实没有在函数范围内的静态变量。 Note that x in this example is only exposed as global to the rest of the module. 请注意,此示例中的x仅作为全局公开给模块的其余部分。 For example, say the code above is in test.py . 例如,假设上面的代码在test.py Now suppose you write the following module: 现在假设您编写以下模块:

from test import foo
x = 100
foo()
foo()

The output will be only 1 and 2 , not 101 and 102 . 输出将仅为12 ,而不是101102

You could also use something like 你也可以使用类似的东西

def static_num2():
    k = 0
    while True:
        k += 1
        yield k

static = static_num2().next

for i in range(0,10) :
    print static()

to avoid a global var. 避免全局变种。 Lifted from this link about the same question. 这个链接中提到了同样的问题。

Not that I'm recommending this, but just for fun: 不是我推荐这个,而是为了好玩:

def foo(var=[1]):
    print var[0]
    var[0] += 1

This works because of the way mutable default arguments work in Python. 这是有效的,因为Python中的可变默认参数的工作方式

The preferable way is to use class or generator ( yield ). 最好的方法是使用生成器yield )。

For the sake of completeness here's a variant w/ closure in Python 3.x: 为了完整起见,这里是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
>>> def foo():
    x = 1
    while True:
        yield x
        x += 1


>>> z = iter(foo())
>>> next(z)
1
>>> next(z)
2
>>> next(z)
3

Here's another dirty cheap way to do it, it's a variation on Tryiptich's answer, but using decorators 这是另一种肮脏的廉价方式,它是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
>>> 
"""    

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM