在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. C++继承细节 -2

    继承与动态内存分配 //基类定义 class BaseClass { private: char *label; public: BaseClass() {} BaseClass(const char ...

  2. 02.将python3作为centos7的默认python命令

    博客为日常工作学习积累总结: 由于个人兴趣爱好对python有了解: 1.安装Python3: 参考博客:https://zhuanlan.zhihu.com/p/47868341 安装依赖包: yu ...

  3. linux系统基础之六--系统引导(基于centos7.4 1708)

  4. ubuntu系统的软件包管理工具

    ubuntu系统的软件包管理工具有两种,一种是离线管理,另一种是在线管理 1.离线管理 dpkg工具可以对本地存放的deb安装包进行安装,卸载,查看状态等. dpkg -i app_name_vers ...

  5. Angular.js进阶

    1.常用指令 <!DOCTYPE html> <html> <head lang="en"> <meta charset="UT ...

  6. 网页股票期货历史数据(API)

    //[和讯数据] //大商所DCE.郑商所CZCE.上期所SHFE3.中金所CFFEX //期货1分钟线http://webftcn.hermes.hexun.com/ ... I1709&d ...

  7. day 22 内置的模块

    1.简单的理解模块 写的每一个py文件都是一个模块,还有一些是我们一直在使用的模块. buildins: 内置模块. print, input random 主要是和随机相关的内容:         ...

  8. linux内核中的IS_ERR()、PTR_ERR()、ERR_PTR()

    IS_ERR宏定义在include/linux/err.h,如下所示: #define MAX_ERRNO 4095 //判断x是不是在(0xfffff000,0xffffffff)之间,注意这里用u ...

  9. Altium Designer常用快捷键

    一:Altium原理图快捷键:    Shift+左键选择    :实现多个目标选择    Ctrl+左键拖动    :保持连线拖动目标        Shift+c       :清除当前过滤(?? ...

  10. python3 练习题100例 (一)

    断断续续的学了很久的python,有很多又忘记了.从今天开始用实例再进行一次学习,并记录.本人小白一个,请大家多多指教. #!/usr/bin/env python3 # -*- coding: ut ...