美文网首页
对python中闭包概念的理解

对python中闭包概念的理解

作者: aier_wiki | 来源:发表于2019-01-25 23:41 被阅读0次

    首先通过一例子直观理解一下闭包是什么

    实现一个函数avg(),每次调用该函数,传入一个数值,返回历史调用中,所有入参的平均值。
    >>> avg(1)
    1.0
    >>> avg(2)
    1.5
    >>> avg(3)
    2.0

    方式一:

    class Averager():
        def __init__(self):
            self.series = []
        def __call__(self, new_value):
            self.series.append(new_value)
            total = sum(self.series)
            return total / len(self.series)
    avg = Agerager()
    avg(1)
    avg(2)
    avg(3)
    

    这种方式是传统的面向对象的实现方式,python还提供一种闭包的机制可以实现上述功能。
    方式二:

    def make_averager():
        series = []
        def averager(new_value):
            series.append(new_value)
            total = sum(series)
            return total / len(series)
        return averager
    
    avg = make_averager()
    avg(1)
    avg(2)
    avg(3)
    

    第二种方式,是定义了一个高阶函数,所谓高阶函数就是入参或者返回值为函数的函数。make_averager()的返回值是一个函数,并且该函数是在自己的函数体内定义的。而且还有一点需要注意,就是内部函数averager()中使用了外部函数的局部变量series。被当做返回值的averager就是所谓的闭包。
    综上,闭包出现的条件如下:

    • 出现函数的嵌套定义。
    • 嵌套函数引用了外层函数第一的变量。
    • 外层函数返回嵌套函数。

    有一点需要注意,为什么make_averager()已经执行完返回了,但averager还能使用make_averager中定义的局部变量呢?
    在python中有一个重要的思想:函数是第一对象。所以函数可以像一般的对象一样,可以含有属性。闭包作为一种函数对象,就拥有自己的属性。avg的属性closure中保存着avg可以使用的外层函数的局部变量。这些变量有一个学术上的名字叫自由变量
    可以通过如下方式查看自由变量的值:

    >>> avg.__closure__[0].cell_contents
    [1, 2, 3]

    相关文章

      网友评论

          本文标题:对python中闭包概念的理解

          本文链接:https://www.haomeiwen.com/subject/wahbjqtx.html