zoukankan      html  css  js  c++  java
  • Python LEGB (Local, Enclosing, Global, Build in) 规则

     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 规则下作用域
  • 相关阅读:
    SQL学习
    FOR XML PATH
    IOS学习网址
    weak nonatomic strong等介绍(ios)
    UVALive3045 POJ2000 ZOJ2345 Gold Coins
    UVA713 UVALive5539 POJ1504 ZOJ2001 Adding Reversed Numbers
    UVA713 UVALive5539 POJ1504 ZOJ2001 Adding Reversed Numbers
    UVA439 POJ2243 HDU1372 ZOJ1091 Knight Moves【BFS】
    UVA439 POJ2243 HDU1372 ZOJ1091 Knight Moves【BFS】
    UVA10905 Children's Game
  • 原文地址:https://www.cnblogs.com/zzyzz/p/7509486.html
Copyright © 2011-2022 走看看