global和nonlocal已经函数的闭包

 

# global 和 nonlocal

# 定义一个不可变变量b 并试图先输出在更改b的值

b = 5
def func(a):
    print(a)
    print(b)
    b += a 

4

---------------------------------------------------------------------------
UnboundLocalError                         Traceback (most recent call last)
<ipython-input-3-74f9771a5f0e> in <module>()
----> 1 func(a = 4)

<ipython-input-1-c4bb2c5c9e48> in func(a)
      4 def func(a):
      5     print(a)
----> 6     print(b)
      7
      8     b += a

UnboundLocalError: local variable 'b' referenced before assignment

此时在print(b) 的时候就会抛出异常
因为在输出b的时候,由于在函数内部试图更改b的值,
所以在打印b的时候会从函数内部局域寻找变量b的值,然而发现并没有给b赋值,所以抛出异常

b = 5
def func(a):
    global b                          
    print(a)
    print(b)
    b += a 

# 在函数内部给b加上global关键字后 ,更改b, 成功输出

func(a = 4)
print(b)

4
5
9

# 加入global后,使得生存于全局作用域的b得以在函数其中被改变,否则这些不可变变量如b 将只能读不能更改
# 但是可变变量如列表 可以在任何位置被更改(如果被定义为全局变量的话)。

# nonlocal
# 理解nonlocal之前先理解 闭包 的概念
# 闭包: 是一种函数,可以保留定义函数时候存在的一些自由变量
# 例如, 有这样一种场景:不断计算新加进来数同前面已经存在数的和。 这个题目可以理解为,已经存在数的和为这个函数的自由变量, 利用闭包来实现

def func_add():
    sum = 0
    def add_newnum(new_num):
        nonlocal sum
        sum += new_num
        print("sum:---%r"%sum)
    return add_newnum

# 调用闭包

cal_sum = func_add()

cal_sum(2)

输出:sum:---2

cal_sum(5)

输出:sum:---7

cal_sum(4)

输出:sum:---11

# 注意到在add_newnum 内层函数中,使用了nonlocal ,他的作用主要是使得外层的变量称为自由变量
# 可以同global一样理解,不过应用场景不同, nonlocal主要应用于这种函数嵌套的内部。

# 闭包为什么能够保留已经存在的自由变量呢?
# 当调用  cal_sum = func_add由于fun_add 函数返回的是内层函数名:add_newnum
# 所以调用cal_sum(2) 相当于调用 add_newnum(2) 但是add_newnum始终是func_add返回的,所以如果不更改add_newnum
# 的引用,将始终保持着cal_sum 和 fun_add的关系,则fun_add里面的自由变量sum的值也就会被更改并保存

# 如果更改func_add的引用,如
add_sum2 = func_add()
add_sum2(4)

# 此时又会创建另一份函数作用空间, 自由变量sum的值将从0开始重新被调用更改。

输出:sum:---4

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值