python 关键字:nonlocal 与 global

nonlocal 意为:非局部的。

主要用于在函数内部定义函数时,内层函数使用外层函数的变量。(函数的函数——闭包,类比C++匿名函数的捕获列表)。

示例:

from typing import List

def func(nums: List[int], val:int):
    
    def add():	
        nonlocal nums	# 引用外层变量 nums
        nums = [i+val for i in nums]
        
    add()       # 调用函数
    print(nums)	# 发现add函数调用之后,被引用的值也变了

func([1,2,3,4,5], 10)

输出结果为:[11, 12, 13, 14, 15]

如果我们将内层add() 函数以参数形式传递,则 外层函数的 nums 不会被修改

from typing import List

def func(nums: List[int], val:int):
    
    def add(nums: List[int], val:int):
        nums = [i+val for i in nums]
        
    add(nums, val)       # 调用函数
    print(nums)

func([1,2,3,4,5], 10)

输出:[1, 2, 3, 4, 5]

扩展:变量的属性:全局变量(G)、内层变量(E),局部变量(L)

  • 全局变量:函数外的变量,所有函数可见
  • 局部变量:在函数内部定义的变量
  • 内层变量:在嵌套函数中,外层函数内定义的变量(或外层函数的参数)
    在这里插入图片描述
    • 如果函数内定义了同名变量(局部变量),则局部变量覆盖全局变量.
      注:局部变量修改之后,会产生一个局部变量,虽然与外部全局变量同名,使其内存地址却不同,不是一个变量。
      在这里插入图片描述
    • 函数内部的函数也可见。如果外层函数和内层函数都可所以使用全局变量。
      在这里插入图片描述
      注:内层函数只能修改外层函数的变量,不能直接修改全局变量在这里插入图片描述
      如果外层函数定义了局部变量,则内层函数使用的是外层函数的局部变量(或者说叫内层变量 Enclosing)在这里插入图片描述
      注:内层函数不可修改内层变量和全局变量。内层函数可以主动声明 nonlocal 引入内层变量,从而对其进行修改,且改变是双向的。在这里插入图片描述

我们发现使用 nonlocal 关键字可以让内嵌函数与父函数更好的“交流”,内层函数可以向外层函数获取数据,同时可以将数据修改后反馈给外层函数。

示例2:自增函数

def increase(start=0,step=1):
    def add():                  # 子函数,以step递增
        nonlocal start
        start += step           # 递增
        return start
    return add


incr = increase(0)              # 从0开始递增
print(incr())
print(incr())
print(incr())
print(incr())
# 输出 1 2 3 4 

incr = increase(10,10)          # 从10开始,每次递增10
print(incr())
print(incr())
print(incr())
print(incr())
# 输出 20 30 40 50

实现嵌套函数中,内外层函数的数据“交流”,如果不使用 nonlocal 关键字,就只能让内层函数通过返回值的方式将数据带出。

此外,也可以使用全局变量(使用global 声明),但这样一来就该全局变量就暴露在父函数的外部了,有被其他人修改的风险。

from typing import List

nums = [1,2,3,4]
def func(val:int):
    
    def add():	
        global nums	# 引用全局变量 nums
        nums = [i+val for i in nums] # 修改全局变量 nums
        
    add()       # 调用函数
    print(nums)	# nums的值被修改

func(10)
print(nums) # 全局同用一个nums,该值为func中被修改的值

注意:nolocal 只能引用内层变量

普通函数使用 nonlocal,error
在这里插入图片描述
内层函数使用nonlocal引用全局变量,error
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_43919932/article/details/123492729
今日推荐