美文网首页
python 闭包

python 闭包

作者: 第八共同体 | 来源:发表于2017-06-13 09:18 被阅读0次

转载自https://serholiu.com/python-closures
了解闭包前,先了解一下变量作用域
看个例子:

def f1(a):
     print(a)
     print(b)

f1(2)
Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    File "<stdin>", line 3, in f1
NameError: global name 'b' is not defined

上面的例子出错并不奇怪,如果我们先给b复制,然后调用f1函数,就不会出错了

b = 3
f1(3)
输出: 3
       3

再看一例:

b = 5
def f2(a):
     print(a)
     print(b)
     b = 6

f2(2)
3 
Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    File "<stdin>", line 3, in f2
UnboundLocalError: local variable 'b' referenced before assignment

这不是缺陷,而是设计选择,python不要求声明变量,但是假定在函数定义体重赋值的变量是局部变量。如果在函数中赋值时想让解释器把 b 当成全局变量,要使用 global 声明。

其实,闭包指延伸了作用域的函数,其中包含函数定义体中引用、但是不在定义体中定义的非全局变量。函数是不是匿名的没有关系,关键是它能访问定义体之外定义的非全局变量。

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(12)

注意,series 是 make_averager 函数的局部变量,因为那个函数的定义体中初始化了series:series = []。可是,调用 avg(10) 时,make_averager 函数已经返回了,而它的本地作用域也一去不复返了。在 averager 函数中,series 是自由变量(free variable).
综上,闭包是一种函数,他会保留定义函数时存在的自由变量的绑定,这样调用函数时,虽然定义作用域不可用了,但是仍能使用那些绑定。注意,只有嵌套在其他函数中的函数才可能需要处理不在全局作用域中的外部变量。

def make_averager():
    count = 0
    total = 0
    def averager(new_value):
        count += 1
        total += new_value
        return total / count
    return averager


avg = make_averager()
avg(10)
Traceback (most recent call last):
...
UnboundLocalError: local variable 'count' referenced before assignment

这是怎么回事?对比之前的例子发现,我们的自由变量的类型是列表,现在是一个不可变的基本类型。当我们在嵌套函数中进行赋值操作时,其会试图把它当做局部变量。报错也就不足为奇了。为了解决这个问题,python3引入了nonlocal声明,他的作用是把变量标记为自由变量,即使在函数中为变量赋予了新值,也会变成自由变量。如果为nonlocal声明的变量赋予新值。闭包中保存的绑定会更新。

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

相关文章

  • python闭包学习

    参考文章 python闭包python闭包一步一步教你认识Python闭包深入浅出python闭包

  • python函数之闭包

    目录 python函数之闭包什么是闭包python中的namespace闭包的条件闭包的优点 python函数之闭...

  • Python 闭包使用注意点

    1 Python 闭包 今天,聊下 python 的闭包。在函数编程中经常用到闭包。 闭包是什么,它是怎么产生的及...

  • python高级之闭包

    python高级之闭包 什么是闭包? 闭包(closure)是函数式编程的重要的语法结构。闭包也是一种组织代码的结...

  • Python 中的闭包

    Python 中的闭包:+ http://python.jobbole.com/82296/

  • python之理解闭包和装饰器

    python之理解闭包和装饰器 1、闭包函数 1.1 python中函数都是对象 结果: 上面定义一个shut函数...

  • 闭包

    浅谈 python 的闭包思想 首先 python的闭包使用方法是:在方法A内添加方法B,然后return 方法B...

  • 2018-11-20

    python函数的闭包 闭包: 嵌套函数调用外部函数的变量 注意: 闭包必须是内部函数调用外部函数定义的变量,这其...

  • Python 入门之 闭包

    Python 入门之 闭包 1、闭包 (1)在嵌套函数内使用(非本层变量)和非全局变量就是闭包 (2)_ clos...

  • Python装饰器(Decorator)完全指南-基础篇

    Decorator基本指南 前提知识 Python中的闭包(closure) 所谓闭包,指的是附带数据的函数对象。...

网友评论

      本文标题:python 闭包

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