Python 的 LEGB 规则(转载)
理解LEGB前,首先需要对Python的作用域、命名空间有一定的了解,话题才能继续展开。
命名空间
命名空间表示变量的可见范围,一个变量名可以定义在多个不同的命名空间,相互之间并不冲突,但同一个命名空间中不能有两个相同的变量名。比如:两个叫“张三”的学生可以同时存在于班级A和班级B中,如果两个张三都是一个班级,那么带来的麻烦复杂很
多了,在Python中你不能这么干。
在Python中用字典来表示一个命名空间,命名空间中保存了变量(名字)和对象的映射关系,在Python中命名空间出现在哪些地方呢?有函数范围内的命名空间(local),有模块范围内的命名空间(global),有python内建的命名空间(built-in),还有类对
象的所有属性组成的命名空间。
命名空间的生命周期
所有的命名空间都是有生命周期的,对于python内建的命名空间,python解析器启动时创建,一直保留直至直python解析器退出时才消亡。而对于函数的local命名空间是在函数每次被调用的时候创建,调用完成函数返回时消亡,而对于模块的global命名空间
是在该模块被import的时候创建,解析器退出时消亡。
作用域
一个作用域是指一段程序的正文区域,可以是一个函数或一段代码。一个变量的作用域是指该变量的有效范围。Python的作用域是静态作用域,因为它是由代码中得位置决定的,而命名空间就是作用域的动态表现。
LGB
Python2.2之前定义了三个作用域,分别是:
global作用域,对应的global命名空间,一个模块最外层定义的一个作用域。
local作用域,对应local命名空间,由函数定义的。
builtin作用域,对应builtin命名空间,python内部定义的最顶层的作用域,在这个作用域里面定义了各种内建函数:open、range、xrange、list等等。
那时的Python作用域规则叫做LEB规则,变量(名字)的引用按照local作用域、global作用域、builtin作用域的顺序来查找。
首先来看一段代码:
a = 1
def foo():
a = 2
print a //[1]
print a //[2]
foo()
[1]处输出结果为2,Python首先会在函数foo定义的local作用域中查找名字a,如果找到了直接输出,没有没找到就会在模块定义的global作用域中查找,如果还没找到,就到Python内建的builtin作用域中查找a,如果还没找到就报异常:NameError: name ‘a’ is
not defined。引用过程如图:
2]处输出结果为1,查找顺序同样是按照LGB规则,只不过这里的local作用域就是global作用域。
LEGB规则
Python2.2开始引入嵌套函数,嵌套函数为python提供了闭包实现。
a = 1
def foo():
a = 2
def bar():
print a //[1]
return bar
func = foo()
func()
函数bar和a=2捆包在一起组成一个闭包,因此这里a=2即使脱离了foo所在的local作用域,但调用func的时候(其实就是调用bar)查找名字a的顺序是LEGB规则,这里的E就是enclosing的缩写,代表的“直接外围作用域”这个概念。查找a时,在bar对应的local作
用域中没有时,然后在它外围的作用域中查找a。LEGB规定了查找一个名称的顺序为:local–>enclosing–>global–>builtin。
Python 的 LEGB 规则(转载)的更多相关文章
- 【Python】 命名空间与LEGB规则
命名空间与LEGB规则 之前隐隐约约提到过一些关于Python赋值语句的特殊性的问题,这个问题的根源就在于Python中的变量的命名空间机制和之前熟悉的C也好java也好都不太一样. ■ 命名空间 所 ...
- python——作用域之LEGB规则
1 变量的作用域 Python是静态作用域,也就是说在Python中,变量的作用域源于它在代码中的位置:在不同的位置,可能有不同的命名空间.命名空间是变量作用域的体现形式. 2 LEGB各自代表的含义 ...
- Python中的LEGB规则
目标 命名空间和作用域——Python从哪里查找变量名? 我们能否同时定义或使用多个对象的变量名? Python查找变量名时是按照什么顺序搜索不同的命名空间? 命名空间与作用域的介绍 命名空间 大约来 ...
- python作用域与LEGB规则
作用域 什么是命名空间 比如有一个学校,有10个班级,在7班和8班中都有一个叫“小王”的同学,如果在学校的广播中呼叫“小王”时,7班和8班中的这2个人就纳闷了,你是喊谁呢!!!如果是“7班的小王”的话 ...
- LEGB规则
链接:https://www.cnblogs.com/GuoYaxiang/p/6405814.html 命名空间 大约来说,命名空间就是一个容器,其中包含的是映射到不同对象的名称.你可能已经听说过了 ...
- python 包导入规则
python 包导入规则,恶心了一天,终于搞清楚了 1.目录 speed data __init__.py __init__.py static templates view __init__.py ...
- python 作用域(LEGB)
def fa(a): b = 200 c = 888 def fb(b): print(b) print(a) print(c) print(sum) return fb c = 2 sum = 10 ...
- Python学习系列(四)Python 入门语法规则2
Python学习系列(四)Python 入门语法规则2 2017-4-3 09:18:04 编码和解码 Unicode.gbk,utf8之间的关系 2.对于py2.7, 如果utf8>gbk, ...
- 转---变量LEGB规则
Python 变量作用域的规则是 LEGB LEGB含义解释: L -- Local(function):函数内的名字空间 E -- Enclosing function locals:外部嵌套函数的 ...
随机推荐
- python升级3.6后 yum出错File "/usr/bin/yum", line 30 ^
问题描述: # yum provides ifconfig File "/usr/bin/yum", line 30 except KeyboardInterrupt, e: ^ ...
- Kuangbin 带你飞-线段树专题 题解
HDU 1166 敌兵布阵 单调更新区间查询和 #include <map> #include <set> #include <list> #include < ...
- 【 Zabbix 】— 监控nginx
一.环境说明 OS:centos6.7 x64 nginx:nginx/1.9.9 ZABBIX:2.4.8 zabbix监控nginx是根据nginx的stub_status模块,抓取status模 ...
- 在Js或者cess后加版本号 防止浏览器缓存
在Js或者cess后加版本号 防止浏览器缓存 客户端浏览器会缓存css或js文件,从而减少加载次数,减少流量,提高网页的访问速度.为了使得每次修改js或者css能生效,可以通过改变版本号来使得客户端浏 ...
- selenium+python在mac环境上的搭建【转载】
前言 mac自带了python2.7的环境,所以在mac上安装selenium环境是非常简单的,输入2个指令就能安装好 需要安装的软件: 1.pip 2.selenium2.53.6 3.Firefo ...
- [libgdx游戏开发教程]使用Libgdx进行游戏开发(10)-音乐和音效
本章音效文件都来自于公共许可: http://files.cnblogs.com/mignet/sounds.zip 在游戏中,播放背景音乐和音效是基本的功能. Libgdx提供了跨平台的声音播放功能 ...
- tomcat虚拟主机
直接看配置文件吧,有点基础的都懂 <Host name="localhost" appBase="webapps" unpackWARs="fa ...
- eclipse中的aptana插件的安装
先下载 aptana插件包 我安装的eclipse版本是 indido版本号的. 三步骤: 1.将aptana解压到eclipse的目录下 2.打开eclipse目录下的dropins文件,新建一 ...
- POJ 2492 A Bug's Life【并查集高级应用+类似食物链】
Background Professor Hopper is researching the sexual behavior of a rare species of bugs. He assumes ...
- scrapy生成csv文件空行、csv文件打开乱码(解决方案)
一.scrapy生成csv文件会有多余的空行 当使用scrapy crawl testspider -o test.csv后,生成的默认csv文件每一行之间是有空行的,解决的方法是修改scrapy的源 ...