码迷,mamicode.com
首页 > 编程语言 > 详细

Python LEGB (Local, Enclosing, Global, Build in) 规则

时间:2017-09-12 13:44:36      阅读:182      评论:0      收藏:0      [点我收藏+]

标签:变量   定义   erro   code   sign   先来   exception   过程   cal   

 1       
       Local 一个函数定义了一个 local 作用域; PyFrameObject 中的 f_local 属性 2 Global 一个 module 定义了一个 global 作用域; PyFrameObject 中的 f_global 属性. 3 BuiltIn open, dir 的作用域等等, python 最顶层的作用域
4 Enclosing 5 例子, 6 b = 2 7 def funcO(): 8 b = 3 9 def funcI(): 10 print(b) 11 return funcI 12 13 f = funcO() 14 f() #1 15 16 Output, 17 3 #1 18 19 例子的输出结果是 3 而不是代码块儿最外层所定义的 b = 2. 20 f() 实际调用的内嵌在 funcO 中的 funcI 函数. funcI 位于 funcO 之内, 所以函数 funcI 的作用域内嵌于函数 funcO 的作用域内. 21 即, 函数 funcO 的作用域是内嵌函数 funcI 的直接外围作用域, 所以例子的结果是 3 而不是 2. 22 单纯按照代码块儿的结构来说, 在 #1 处 ‘b = 3‘ 这个约束已经不再对 ‘f()‘ 这个调用起作用, 但是从打印的结果来看显然不是这样(依然起作用). 23 Python 虚拟机在执行 f = funcO() 的时候会执行 def funcI(): (因为 函数 funcO return 了 funcI 函数对象), 24 就在这个时候 约束b = 3 与函数对象 funcI 捆绑了一起, 并把捆绑后的街哦过返回, 这个捆绑起来的整体被称为 闭包(捆绑 一词可以理解为 直接外围作用域 的绑定过程). 25 闭包是 LEGB 规则中的 E -> enclosing 的首字母, 表示的是 直接外围作用域 这个概念. 26 27 global 关键字, 28 例子, 29 c = 1 30 def func1(): 31 print(c) 32 33 def func2(): 34 print(c) 35 c = 3 36 print(c) 37 38 func1() 39 func2() 40 41 Output, 42 1 # func1() 的打印 43 func2() # func2() 的打印 44 print(c) 45 UnboundLocalError: local variable c referenced before assignment 46 47 func1 和 func2 同是对直接外围作用域的搜索, 为什么一个正确搜索约束 c = 1,另一报错呢? 48 先来了解一个名字的定义 - 最内嵌套作用域规则. 49 最内嵌套作用域规则:由一个赋值语句引进的名字在这个赋值语句所在的作用域里是可见(起作用)的, 50 而且在其内部嵌套的每个作用域里也可见,除非它被嵌套于内部的, 51 引进同样名字的另一条赋值语句所遮蔽/覆盖。 52 53 从 exception 中得知, 变量 c 没有被定义. 上述问题就出现在定义的后半句,‘除非’分句 - 除非它被嵌套于内部的, 54 引进同样名字的另一条赋值语句所遮蔽/覆盖。 恰巧紧接着报错处, 通过赋值语句引进了一个同名约束(c = 3),进而破坏了最内嵌套作用域规则. 55 56 现在尝试修改这个引用错误, 57 c = 1 58 def func1(): 59 print(c) #1 60 61 def func2(): 62 global c #2 在引用之前通过 global 关键字指定作用域 63 print(c) #2 64 c = 3 65 print(c) #3 66 67 func1() 68 func2() 69 print(c) #4 70 71 Output, 72 1 #1 73 1 #2 python 理解了编程者的意图 74 3 #3 75 3 #4 76 进一步再看一个闭包的例子, 77 d = 1 78 def func2(): 79 d = 3 80 def func2I(): 81 global d 82 print(d) #1 83 d += 4 #2 重写直接外层作用域 84 print(d) #2 85 return func2I 86 87 abc = func2() 88 abc() 89 print(d) #3 90 91 Output, 92 1 #1 global 关键字 打破 LEGB 规则, 限定引用直接外层作用于 93 5 #2 直接外层作用于被重写 94 5 #3 被重写的‘直接外作用域’(代码块儿最外层的 ‘d = 1‘ 这个约束)作用于 LEGB 规则下作用域

 

Python LEGB (Local, Enclosing, Global, Build in) 规则

标签:变量   定义   erro   code   sign   先来   exception   过程   cal   

原文地址:http://www.cnblogs.com/zzyzz/p/7509486.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!