在 Python 中交替使用类/全局变量和闭包

我遇到了 python 中的闭包,并且我一直在围绕这个主题进行修补。


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


Q1: [replacing classes]


从该类创建的任何实例都datafactory将拥有自己的数据列表,因此每次附加到该对象的列表都会导致增量行为。我了解 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

我尝试用闭包替换它,它成功了,但我对为什么/如何发生这种情况的理解有点模糊。


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的函数定义以及一起发送的变量,如果它是这样的,我会理解输出:incrementdata


1

1

2

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


注意:我知道这种行为通常存在于使用默认参数定义的函数中,例如def func(val, l = []):在每次 fn 调用时不会清除列表,而是使用新元素/附加更新,这也是我不完全理解的.


我真的很感激对这两种情况(OO 和闭包)中发生的事情进行学术解释。


Q2: [replacing use of global]


有没有一种方法可以在不使用全局变量或返回语句的情况下使用闭包来增加以下变量?


a = 0

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


def inc(a):

    a += 1


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

感谢您的时间。


阿晨1998
浏览 106回答 0
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。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python