在Python中,一个变量的scope范围从小到大分成4部分:Local Scope(也可以看成是当前函数形成的scope),Enclosing Scope(简单来说,就是外层函数形成的scope),Global Scope(就是当前文件形成的scope),Builtins Scope(简单来说,就是Python内置的变量位于最顶层的scope)。当Python开始查找一个非限定的变量名时(像obj.attr中的attr,就是一个被限定的变量名字,它被限定在obj对象中,而普通的变量名就是没有限定的),总是从当前变量名所处的scope开始,顺着前面提到的scope链开始往上查找,一旦查找到就不会往上再继续查找,如果查找完整个scope链还是没找到,Python会报错。

上面提到的变量名查找顺序,可以简单的记为LEGB(每一个scope的首字母),而global和nonlocal,可以改变查找顺序。

global

在文件中声明的变量自动成为global的,而如果想在一个函数里面声明一个全局变量,就需要使用global关键字:

global var1, var2, ...     # 多个变量用逗号隔开

对于global关键字,需要注意以下几点:

1 当Python看到一个变量由global变量声明,开始查找的scope不是从这个变量当前所在的scope开始查找,而是从Global Scope开始查找;如果Global Scope没有找到,就会继续到Builtins Scope查找;

2 global关键字声明的对象允许赋值,如果这个变量之前不存在,那么,这次赋值就是创建了一个全局变量;如果这个变量之前存在,那么,这次赋值就改变了这个全局变量的值:

def test():
global x
x = 1 # x之前不存在,因此在Global Scope创建了一个全局变量x x = 1 def test():
global x
x = 99 # x之前在Global Scope中已经存在,因此这里是改变x的值

3 只要被global关键字声明的变量,都会成为全局变量,如果该变量原来不是全局变量,也会如此,并且,如果之前Global Scope里面有同名变量,那么被global声明的变量会取代这个同名变量:

x = 99

def test():
x = 88
global x # 这样做的话Python会产生警告:SyntaxWarning: name 'x' is assigned to before global declaration >>>print(x) # 一开始访问的是全局变量x
>>>99
>>>test() # 执行test函数之前,原本函数里面的局部变量x成为了全局变量,并取代原来的全局变量
>>>print(x) # 现在访问的是取代后的全局变量x,值变为88
>>>88 # 在看一个例子,加入开始没有定义全局变量x
def test():
x = 88
global x # 仍会产生相同的警告 >>>test()
>>>print(x) # 打印结果为88!!!
>>>88

nonlocal

nonlocal是Python 3.X加入进来的关键字,Python 2.X中没有。在Python中,嵌套函数是可以访问外部函数的变量的(至少在>Python 2.2的版本是这样的,在Python 2.2之前的版本中,变量的查找从当前函数开始,然后直接到Global Scope,Builtins Scope,跳过了外层函数),但是却不可以改变外部函数变量的值,如果确实要改变,就的使用nonlocal变量进行声明:

nonlocal var1, var2,...   # 只在Python 3.X中支持,多个变量用逗号隔开

对于nonlocal关键字,需要注意以下几点:

1 nonlocal关键字只在Python 3.X中支持,Python 2.X没有这个关键字;

2 nonlocal关键字只可以在函数内部使用,在其他地方使用会报错;

3 nonlocal声明的变量,之前必须已经存在(并且是在外部函数中存在),如果变量不存在就对这个变量赋值,会报错,这点和global关键字不一样:

# 变量存在于Global Scope
x = 99 def test():
nonlocal x # 报错:SyntaxError: name 'x' is assigned to before nonlocal declaration # 变量存在于当前函数
def test():
x = 99
nonlocal x # 报错:SyntaxError: name 'x' is assigned to before nonlocal declaration

4 对于nonlocal声明的变量,只会在外部函数中查找该变量,不会在Global Scope和Builtins Scope中查找

Python中的global和nonlocal的更多相关文章

  1. Python中关键字global与nonlocal的区别

    版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/xCyansun/article/details/79672634终于下定决心学习Python了.既然 ...

  2. 转载 Python中关键字global与nonlocal的区别

    转载自CSDN 雁丘1990, 原文地址: https://blog.csdn.net/xcyansun/article/details/79672634 这篇文章写的很赞, 条理清晰, 分析循序渐进 ...

  3. python中全局global和局部nonlocal命名空间

    python中全局global和局部nonlocal命名空间 局部名称空间对全局名称空间的变量可以引用,但是无法改变. count = 1 def func1(): count = 2 print(c ...

  4. python 中使用 global 引发了莫名其妙的问题

    哪里出问题了 python 中,使用 global 会将全局变量设为本函数可用.同时,在函数内部访问变量会先本地再全局. 在嵌套函数中,使用 global 会产生不合常理的行为. 上代码: In [9 ...

  5. python 作用域,global与nonlocal的区别

    在Python中并不是所有的语句块中都会产生作用域.只有当变量在Module(模块).Class(类).def(函数)中定义的时候,才会有作用域的概念. 如果在函数中要对全局变量做改变可以使用glob ...

  6. 07.python函数作用域global、nonlocal、LEGB

    函数作用域 作用域 一个标识符的课件范围,这就是标识符的作用域,一般常说的是变量的作用域 def foo():    x = 100 print(x) # 可以访问到吗 上例中x不可以访问到,会抛出异 ...

  7. python中global 和 nonlocal 的作用域

    python引用变量的顺序: 当前作用域局部变量->外层作用域变量->当前模块中的全局变量->python内置变量 . 一 global global关键字用来在函数或其他局部作用域 ...

  8. python中global和nonlocal用法的详细说明

    一.global 1.global关键字用来在函数或其他局部作用域中使用全局变量.但是如果不修改全局变量也可以不使用global关键字.   gcount = 0 def global_test(): ...

  9. python中global 和 nonlocal的使用

    1.global关键字用来在函数或其他局部作用域中使用全局变量.但是如果不修改全局变量也可以不使用global关键字. gcount = 0 def global_test(): gcount+=1 ...

随机推荐

  1. ORACLE GOLDEN GATE oracle同步数据至kafka

    一.服务器信息 ip   软件版本 ogg版本 软件包 操作系统版本 OGG安装路径 10.1.50.52 源 oracle11.2.0.4 12.2.0.1.1 V100692-01.zip cen ...

  2. [读书笔记] Spring MVC 学习指南 -- 第一章

    控制反转(Inversion of Control, IoC)/ 依赖注入: 比如说,类A依赖于类B,A需要调用B的某一个方法,那么在调用之前,类A必须先获得B的一个示例引用. 通常我们可以在A中写代 ...

  3. 走进MySQL

    MySQL 是最流行的关系型数据库管理系统,在 WEB 应用方面 MySQL 是最好的 RDBMS(Relational Database Management System:关系数据库管理系统)应用 ...

  4. go加密算法:CBC对称加密(一)--DES

    package main import ( "bytes" //"crypto/aes" "crypto/cipher" "cry ...

  5. wdcp v3 pureftpd 无法登录问题解决

    wdcp v3 新建站点和ftp账号 单位无法登录ftp 在端口中也确实可以看到有进行在登录状态 错误原因: 防火墙端口没有开启该端口范围  20000-30000 这时候发现 改端口为20078  ...

  6. 解决thinkphp query()执行原生SQL语句成功结果报错的问题

    1.query方法 query方法用于执行SQL查询操作,如果数据非法或者查询错误则返回false,否则返回查询结果数据集(同select方法). 2.execute方法 execute用于更新和写入 ...

  7. sourcetree .git 强制忽略指定文件不提交

    在公司写项目,大部分都会用到 svn 或 git 提交代码到服务器.我们公司用的GIT,每个程序员有自己的独立分支,各写各的代码互不冲突,最终合并到主分支再解决相同代码冲突问题.这时候会遇到一些配置文 ...

  8. 通过samba服务将centos7指定文件挂载到window下

    做嵌入式开发,windows下编辑代码,虚拟机上编译,为了方便打算在虚拟机下搭一个samba服务器,将文件夹映射到windows下,搜索网上的方法,内容大同小异,试了半天终于成功了.特此记录一下步骤, ...

  9. mRNA翻译成蛋白

    dna = "ATGCACGTGCGCTCACTGCGAGCTGCGGCGCCGCACAGCTTCGTGGCGCTCTGGGCACCCCTGTTCCTGCTGCGCTCCGCCCTGGCCG ...

  10. 博科Brocade 300光纤交换机配置zone教程

    光纤交换机作为SAN网络的重要组成部分,在日常应用中非常普遍,本次将以常用的博科交换机介绍基本的配置方法. 博科300实物图: 环境描述: 如上图,四台服务器通过各自的双HBA卡连接至两台博科300光 ...