如何在函数中保存状态?

WoJ*_*WoJ 5 python variables scope python-3.x

使用类时,我可以使用属性保留状态:

class Hello:

    def __init__(self):
        self.hello = 1

    def add_one(self):
        if self.hello < 3:
            self.hello += 1
        else:
            self.hello = 1

h = Hello()
for _ in range(5):
    h.add_one()
    print(h.hello)

# output
2
3
1
2
3
Run Code Online (Sandbox Code Playgroud)

在调用之间h.add_one(),状态保存在 中h.hello

函数中是否有等效的机制?类似的东西

def add_one():
    a_special_kind_of_variable_which_is_not_reinitialized hello
    if hello_is_not_initialized:
        hello = 1
    if hello < 3:
        hello += 1
    else:
        hello = 1
    return hello

for _ in range(5):
    print(add_one())

# same output as above
Run Code Online (Sandbox Code Playgroud)
  • 使用全局变量将是一个解决方案,但我想避免这种情况。
  • 将返回值传递回函数以强制状态是另一种选择,但我希望有一种方法可以在没有外部依赖的情况下将状态保留在函数内。

che*_*ner 5

Python 没有 C 风格的静态变量。但是,您可以使用闭包来模拟它们。

def make_add_one():
    x = 0
    def _():
        nonlocal x
        if x < 3:
           x += 1
        else:
            x = 1
        return x
    return _

add_one = make_add_one()

for _ in range(5):
    print(add_one())
Run Code Online (Sandbox Code Playgroud)

对象(数据与函数)和闭包(函数与数据)之间存在二元性;与Carcigenicate 定义的类进行比较(稍作修改):

class AddOne:
    def __init__(self):
        self.hello = 0

    def __call__(self):
        if self.hello < 3:
            self.hello += 1
        else:
            self.hello = 1
        return self.hello

add_one = AddOne()
for _ in range(5):
    print(add_one())
Run Code Online (Sandbox Code Playgroud)

可以看到以下对应关系:

  • AddOne↔ 外部函数make_add_one
  • 实例AddOne()↔ 内部函数make_add_one()
  • 实例属性↔内部AddOne().hello非局部变量hellomake_add_one