Python 闭包

理解 Python 闭包,感到困惑的点:

>>> x = 1
>>> def f():
    y = []
    def ff():
        y += [11] # 问题应该是出现在变量名的使用上
        return y
    return ff

>>> l = f()
>>> l()

Traceback (most recent call last):
  File "<pyshell#144>", line 1, in <module>
    l()
  File "<pyshell#142>", line 4, in ff
    y += [11]
UnboundLocalError: local variable 'y' referenced before assignment

# 抛出未绑定的局部变量异常,为什么呢? OK,换一种写法:

>>> def f():
    y = []
    def ff():
        y.append(11)
        return y
    return ff

>>> l = f()
>>> l()
[11]
>>> l()
[11, 11]
>>> l()
[11, 11, 11]
# 一切正常

那上面为什么会抛出UnboundLocalError异常呢?再换一种写法:

>>> def f():
    y = [0]
    def ff():
        y[0] += 1 # 修改变量的引用,不会抛出异常
        return y
    return ff

>>> l = f()
>>> l()
[1]
>>> l()
[2]
>>> l()
[3]

总结:
一个函数的调用需要读取或修改该函数外部作用域的变量时:
1. 直接读取该变量,(变量解析的 LEGB 法则,即标识符的搜索顺序:Local -> Enclosing(直接外围空间) -> Global -> Builtin),在任何一层找到该变量即停止搜索,若直到 Builtin 层仍未找到该变量则抛出NameError异常;
2. 若需要修改变量,确保操作该变量的引用,否则抛出UnboundLocalError异常。


Lambda 、作用域

lambda 定义了新的作用域,使用 lambda 与 def 定义的函数,在作用域方面没有本质的不同。都是在函数调用时按照 LEGB 顺序解析变量。

>>> x = 5
>>> def f():
...     y = 10
...     bar = lambda : x + y
...     print bar() # bar() 被调用使按 LEGB 顺序解析变量
...     y = 0
...     print bar() # 同上

>>>f()
15
5
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值