交替使用 classes/globals 和 Python 中的闭包

Alternating the use of classes/globals with closures in Python

我在 python 中遇到过闭包,我一直在研究这个问题。

如果我在这里错了请纠正我,但我对何时使用闭包的理解(通常)是它可以用作小 classes (q1) 并避免使用全局变量 (q2).

Q1: [replacing classes]

datafactory class 创建的任何实例都将拥有自己的数据列表,因此每次附加到该对象的列表都会导致增量行为。我了解 OO POV 的输出。

class datafactory():

    def __init__(self):
        self.data = []

    def __call__(self, val):

        self.data.append(val)
        _sum = sum(self.data)

        return _sum

incrementwith = datafactory()
print(incrementwith(1))
print(incrementwith(1))
print(incrementwith(2))
OUTPUT: 
1
2
4

我尝试用闭包替换它,它成功了,但我对 why/how 这种情况的理解有点模糊。

def data_factory():
    data = []

    def increment(val):

        data.append(val)
        _sum = sum(data)
        return _sum

    return increment

increment_with = data_factory()

print(increment_with(1))
print(increment_with(1))
print(increment_with(2))
OUTPUT:
1
2
4

我得到的是 data_factory return 嵌套 increment 函数的函数定义以及 data 变量一起发送,我如果它是这样的,就会理解输出:

1
1
2

但是 data 列表究竟是如何在每次调用中持续存在的? 函数中定义的变量不应该在函数完成执行后消失,并在下一次 fn 调用时重新生成和清除吗?

注意:我知道这种行为通常存在于使用默认参数定义的函数中,例如 def func(val, l = []): 其中列表不会在每次 fn 调用时被清除,而是用新的 element/append],这也是我没有完全理解的地方。

我非常希望对这两种情况(OO 和闭包)中发生的事情进行学术解释。

Q2: [replacing use of global]

有没有办法在不使用全局变量或 return 语句的情况下使用闭包来递增以下变量?

a = 0
print("Before:", a) # Before: 0

def inc(a):
    a += 1

print("After:", a) # After: 0

感谢您的宝贵时间。

对于第一个问题,经过一番挖掘后我发现将可变变量作为默认参数传递并不是一个好的做法: https://florimond.dev/blog/articles/2018/08/python-mutable-defaults-are-the-source-of-all-evil/#:~:text=of%20this%20mess.-,The%20problem,or%20even%20a%20class%20instance.