python3 global 与 nonlocal 的区别

问题

num = 10
def changeNum():
  num=20
  print(num)


changeNum() # 20
print(num)  # 10
复制代码

在函数中,直接修改外部变量,修改不生效。

原因:

python 变量访问规则

由于 python 中变量不需要先定义,赋值即可绑定,所以在 局部作用域 进行对 变量 赋值操作,不会关联到全局作用域(如果要关联,那每定义一个变量,就要在父级,全局查一遍是否存在这个变量,那额外花销太大),而是直接创建一个当前局部作用域局部变量,同时会形成 暂时性死区(不可在变量声明之前调用) 的现象。

解决

总体思路:通过关键字,将上级或者全局变量映射到当前局部作用域。

global

x=10

# 局部作用域
def changeNum(): 
  # print(x) # SyntaxError: name 'x' is used prior to global declaration
  global x
  x = 20
  a = 'kkk'
  def changeStr():
    global a
    a = 'bbb'

  changeStr()
  print(a) # kkk

changeNum()
print(x) # 20
print(a) # bbb
复制代码
  1. global 关键字,能将 全局作用域 的变量映射到当前作用域,修改后,能生效;
  2. 不可以在 global 字之前使用变量;
  3. 嵌套函数中的变量,不属于全局作用域,所以使用 global 不生效;
  4. 如果全局环境中没有声明的变量,再局部环境使用 global 后,该变量即为 全局变量 ,在全局依然能访问。

nonlocal

x = 10

# 局部作用域
def changeNum(): 
  # nonlocal x # SyntaxError: no binding for nonlocal 'x' found
  x = 20
  a = 'kkk'
  b = 'ggg'
  def changeStr1():
    nonlocal a
    a = 'bbb'

    def changeStr2():
      nonlocal b
      b = 'ccc'

    changeStr2()

  changeStr1()
  print(a) # bbb
  print(b) # ccc

changeNum()
print(x) # 10
复制代码
  1. nonlocal 不可以绑定全局作用域的变量;
  2. nonlocal 可以绑定嵌套函数中任何祖先级的 局部变量

nonlocalglobal 的区别

最核心一点的是,global 是让 局部作用域 访问全局变量的关键字;nonlocal 是让底层的 局部作用域 可以访问父级(祖父级)作用域中的 局部变量

猜你喜欢

转载自juejin.im/post/7042538401152630814