【python】global和nonlocal关键字

举报
子都爱学习 发表于 2021/11/12 07:59:14 2021/11/12
【摘要】 上一篇介绍的python的作用域:变量引用的顺序: 当前作用域局部变量->外层作用域变量->当前模块中的全局变量->python内置变量 。这一篇我们理解下python和作用域相关的两个关键字global,nonlocalglobal 表示将变量声明为全局变量nonlocal 表示将变量声明为外层变量(外层函数的局部变量,而且不能是全局变量)global函数外部定义的变量(即global范围...

上一篇介绍的python的作用域:

变量引用的顺序: 当前作用域局部变量->外层作用域变量->当前模块中的全局变量->python内置变量 。

这一篇我们理解下python和作用域相关的两个关键字globalnonlocal

  • global 表示将变量声明为全局变量
  • nonlocal 表示将变量声明为外层变量(外层函数的局部变量,而且不能是全局变量)

global
函数外部定义的变量(即global范围),在函数内部可以引用,但是不能修改。
如果函数中要使用一个外层(这里是global)的变量,若函数内部使用global标记该变量,那么在函数内尽可以“读取”该变量;若要在函数内修改该global变量,则需要用global语句,函数对该变量的修改也会体现到global作用域。

# 全局变量可以在函数中被引用
glob= '这是一个全局变量'
def foo():
    print(glob)
foo()
# 这是一个全局变量


# 全局变量不能在函数中被修改
def foo1():
    print(glob)
    glob = 1
    print(glob)
foo1()
# UnboundLocalError: local variable 'glob' referenced before assignment


# 使用global关键字后,全局变量可以在函数中被修改
def foo2():
    global glob
    print(glob)
    glob = 1
    print(glob)
foo2()
print(glob)
# 这是一个全局变量
# 1
# 1


    



nonlocal
nonlocal指定在当前作用域使用上层作用域中(但排除global作用域)的变量名

nonlocal只能在函数内的函数中使用,如果直接在全局作用域下定义的函数中使用该语句,会报错

def yun():
   nonlocal y
# 函数中使用,直接报语法错误
# SyntaxError: no binding for nonlocal 'y' found



闭包中正确使用nonlocal的例子

n=1
def outer():
    n='n'
    print(n)
    def inner():
        nonlocal n
        n='nn'
        print(n)
    inner()
    print(n)

outer()
# n   先打印外层定义的n
# nn  内层函数修改了外层函数中的变量n
# nn  然后外层函数再打印n就变成了内部函数修改后的值



再看一个例子

n=1
def outer():
  # print(n)
  n='n'
  print(n)
  def inner():
    global n  #和上例比这里改用global
    #nonlocal n
    n='nn'
    print(n)
  inner()
  print(n)

 
outer()
# n  先打印外层函数的n
# nn 修改全局变量n并打印  
# n 可以看到外层函数的n并没有修改而全局变量n被inner函数修改



【特别注意】
nonlocal,如果在闭包内给该变量赋值,那么修改的其实是闭包外那个作用域中的变量。
global,用来表示对该变量的赋值操作,将会直接修改模块作用域里的那个变量。

python不允许同一个局部作用域中的同一个变量名有多种角色,即不允许在 global a 这句话之前是局部变量、之后是全局变量。
这里的规则仅是针对不可变元素,如字符串数字等,对于列表或字典等可变元素无效。
深层原因是向可变对象中增删改元素并不是对该对象本身的修改
同时当我们使用可变变量作为形参时要慎重思考

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。