Python特有的语法规则和诸如Java等其他静态类型语言有很大不同,而作用域规则则是其一,初识Python会遇到一些问题,现在对Python作用域相关的知识做个总结。

Python作用域规则一句话概括就是 LEGB 规则; L 代表 Local、E 代表 enclosing、G 代表 Global、B 代表 Builtin

作用域由 Python 的代码文本决定,一个模块定义了一个 Global 作用域、一个函数定义一个 Local 作用域; 作用域与一个名字空间一一对应,名字空间是一个mapping对象,它存储了当前作用域中的变量名字以及名字所绑定的对象。不同作用域中的变量名是不相关的。大概关系如下图:

假设一个模块中定义一个函数,在函数外面定义了变量a,b; 在函数中定义变量a,c, 模块本身也有Local命名空间,只是和 Global 是同一个命名空间。

除了 Global 和 Local 作用域,还有一个最顶层的作用域 – Builtin 作用域。 Builtin 作用域对应于 Builtin 命名空间,里面包含了内置函数和其他一些内置的东西。既然是系统内置的模块,地位自然非同一般,可以认为在任何模块作用域外面都有一层 Builtin 作用域。

当引用一个变量时,会首先在当前 Local 作用域的命名空间中查找,没找到就去 Global 命名空间查找,再没找到就会去 Builtin 命名空间查找,再没找到就会抛出异常。

a = 1
b = 2def func():a = 3c = 4print(a)    #打印3  Local 中找到,直接打印print(b)    #打印2  Local 中不存在,去 Global 找print(abs(-5))    #打印5 abs先去 Local 再去 Global找,都没找到,去 Builtin 中找#print(haha)       #报错,name 'haha' is not definedprint(a)        #打印 1  直接在 Global 中找

在 func 中通过 b = 10 这样的语句是不会修改 Global 中的 b 的,而是会在 Local 命名空间中添加一个名字 ‘b’ 并绑定值为 10

要想修改 Global 中的 b, 需要这样

前面介绍了 L G B 所代表的作用域以及它们之间的关系,还有查找一个变量的顺序 L -> G -> B,下面介绍比较特殊的 E。
当在函数内部再定义一个函数时,就形成了函数嵌套,形成了闭包,而内层函数的直接外部作用域是外层函数,这块作用域就是 enclosing, 例:

a = 1
def wrapper():a = 2def inner():print(a)inner()wrapper() #执行这句后,会打印2

这里内层函数会先找最内层作用域,即 inner 的 Local 命名空间,没有找到则会到 wapper 的 Local 命名空间找,找到后打印,找不到时才会再往 Global 中去找。 这里在 inner 中直接去修改 wrapper 中的变量还是不起作用的,只会在inner 的 Local 命名空间中添加名字和值,要想修改 enclosing 作用域中的值,
需要这样:
在 Python2 中:

def wrapper():a = 1count = [a]def inner():count[0] += 1print 'a:', areturn count[0]return innerinner = wrapper()
print inner()
print inner()
#打印
# a: 1
# 2
# a: 1
# 3

这里是借用一个列表间接修改,实际 a 的值并没有变。

Python3中,提供了一个 nonlocal 关键字,用于直接修改闭包变量

def wrapper():a = 1def inner():nonlocal aa += 1return areturn innerinner = wrapper()
print(inner())
print(inner())

至此所有的作用域介绍完毕,总的来说当寻找某个变量时从最内层开始找,按照
L -> E -> G -> B 的顺序逐层查找。


其他问题:

a = 1def func():print(a)a = 1print(a)func()

执行上面的代码会报错 UnboundLocalError: local variable ‘a’ referenced before assignment,这是因为在执行第一句 print 时直接就去 Local 中去找了,并且还找到了,但是不幸的是,当前 Local 中的 a 虽然找到了,但是还不可用,赋值语句在下面,Python 是在编译完成后,未执行程序时,就已经知道了 Local 作用域中藏着一个 a,这体现了 Python 作用域的静态性。

在作用域的问题上,只要记住以文本定义为准,而不看在哪里调用的,可以理解为在 python 解释器执行代码时,定义一个函数时,就已经将 Global 和 Local 命名空间绑定到函数对象上了,这个 Global 和 Local 就是函数执行时的环境。

另外内置函数 globals() 和 locals() 分别返回了当前 Global 命名空间和 Local 命名空间的内容。

Python作用域总结相关推荐

  1. 对于python 作用域新的理解

    今天看Python习题,看到如下题目 def num():return [lambda x: i*x for i in range(4)] print([m(2) for m in num()]) # ...

  2. python作用域链_Python 中的作用域准则

    0x00 前言 因为最早用的是 Java 和 C#,写 Python 的时候自然也把 Python 作用域的想的和原有的一致. Python 的作用域变量遵循在大部分情况下是一致的,但也有例外的情况. ...

  3. python作用域初探

    python作用域初探 前言:在正式探讨前先抛出几个基本的概念,这几个概念是官方文档中有声明的概念,不过这些概念都包含有自己的一些理解,所以难免有些不太准确,请大家多多指正. 1.基本概念:     ...

  4. 第3关:函数的使用范围:Python 作用域

    任务描述 相关知识 编程要求 测试说明 任务描述 函数是有使用范围的,在一个模块中,我们可以定义很多函数和变量.但我们希望有的函数和变量别人可以使用,有的函数和变量仅仅可以在模块内部使用,这就是 Py ...

  5. python作用域问题

    python作用域问题 有一句话很重要,要说在前面:类型是属于对象的,并不是属于变量: 而在python这门语言中,有一种说法叫做"鸭子类型":"当看到一直鸟走起来像鸭子 ...

  6. Python入门之函数结构——第3关:函数的使用范围:Python作用域

    任务描述 函数是有使用范围的,在一个模块中,我们可以定义很多函数和变量,但我们希望有的函数和变量别人可以使用,有的函数和变量仅仅可以在模块内部使用.这就是Python作用域的相关问题. 本关的目标就是 ...

  7. python 作用域 前缀_Python面试题:杂项内容

    1.解释一下 Python 中 pass 语句的作用? 答:pass 实际上就是一个占位符,在写一个函数但是不确定里面写啥的时候,这个时候可以使用 pass.示例如下def foo(): pass 2 ...

  8. python 作用域 前缀_Python 之作用域和名字空间

    作用域与名字空间 Python有一个核心概念是名字空间(namespace),namespace是一个name到object 的映射关系,Python有很多namespace,因此,在代码中如果碰到一 ...

  9. python作用域-Python之函数作用域

    1.作用域介绍 也叫名称空间全局名称空间:创建的存储"变量名与值的关系"的空间叫做全局名称空间 局部名称空间:在函数的运行中开辟的临时的空间叫做局部名称空间 内置名称空间:内置名称 ...

最新文章

  1. Python的控制语句1
  2. python getopts_getopts用法
  3. mysql_ping()函数的作用以及返回值的类型正确的是,[单选] mysql_ping()函数的作用以及返回值的类型正确的是:()...
  4. logisim无法打开解决办法
  5. JAVA获取服务器路径的方法
  6. LeetCode-数组-三数之和
  7. 怎样把Linux的私钥文件id_rsa转换成putty的ppk格式
  8. mysql数据库视图_MySQL数据库8(二十)视图
  9. 易语言单窗口单ip软件源码_梦幻西游怎样多开ip转金?老玩家的十大转金秘籍奉上...
  10. H13-531 华为HCIE云计算笔试题库整理
  11. 查看Jquery版本
  12. echarts 生成 迁徙图_echarts迁徙图
  13. 如何选择频谱监测的天线?
  14. 参加江大白手把手教你-----AidLux智慧安防AI训练营
  15. 如何在SuperMap iDesktop制作卫星地图
  16. 尚上优选社区团购业务流程及微服务技术实现
  17. Mac -- 启动ssh服务
  18. python中整数的长度_Python中正整数的位长度
  19. MySQL事务——事务隔离界别,MVCC
  20. 用c语言计算正四棱锥的体积,《计算机图形学》习题与解答.doc

热门文章

  1. 泛微协同OA农业电子商务解决方案
  2. 蜂食记小程序:“吃货们”你们的福利来啦!
  3. 记录一下Oracle常用的索引相关的sql语句
  4. 爱她,给她换动感地带
  5. 在VMware中制作linux虚拟机模板
  6. mudo atomic详解
  7. 白皮书 | 智慧公路体系架构、关键技术、生态体系及建设实践
  8. 7-4 列车调度 (25分)
  9. 电脑命令行发wifi
  10. 励志女性-选自《中国妇女杂志》-20210117