python学习交流

Python 关键知识4:闭包

2018-12-06  本文已影响11人  水之心

变量作用域

从内层函数的角度看,变量使用的两个维度

变量作用域识别三要素

三种变量作用域(声明)

划重点:

金句:

为什么会有 nonlocal 关键字?

什么是闭包?

闭包有什么用呢?

  1. 共享变量的时候避免使用了不安全的全局变量
  2. 允许将函数与某些数据关联起来,类似于简化版面向对象编程
  3. 相同代码每次生成的闭包,其延伸的作用域都彼此独立(计数器,注册表)
  4. 函数的一部分行为在编写时无法预知,需要动态实现,同时又想保持接口一致性
  5. 较低的内存开销:类的生命周期远大于闭包
  6. 实现装饰器(装饰器的本质是一个闭包,而 @ 仅仅是一个语法糖)

下面我们要实现一个任务:每次调用便计算之前所有的数的平均值。

实现版本1:类实现

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 = Averager()
avg(10), avg(11), avg(21)
(10.0, 10.5, 14.0)

版本2:闭包实现

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(10), avg(11), avg(21)
(10.0, 10.5, 14.0)

由于每次都需重新计算总数,做了许多不必要的重复,为了简化版本2,我们可以这样:

版本3:优化的闭包实现

def make_averager():
    count = 0
    total = 0

    def averager(new_value):
        nonlocal count, total
        count += 1
        total += new_value
        return total / count

    return averager

avg = make_averager()
avg(10), avg(11), avg(21)
(10.0, 10.5, 14.0)

一步一步教你认识Python闭包

上一篇 下一篇

猜你喜欢

热点阅读