Python命名空间详解


Posted in Python onAugust 18, 2014

通俗的来说,Python中所谓的命名空间可以理解为一个容器。在这个容器中可以装许多标识符。不同容器中的同名的标识符是不会相互冲突的。理解python的命名空间需要掌握三条规则:

第一,赋值(包括显式赋值和隐式赋值)产生标识符,赋值的地点决定标识符所处的命名空间

第二,函数定义(包括def和lambda)产生新的命名空间

第三,python搜索一个标识符的顺序是"LEGB"。

所谓的"LEGB"是python中四层命名空间的英文名字首字母的缩写。
最里面的一层是L(local),表示在一个函数定义中,而且在这个函数里面没有再包含函数的定义。
第二层E(enclosing function),表示在一个函数定义中,但这个函数里面还包含有函数的定义,其实L层和E层只是相对的。
第三层G(global),是指一个模块的命名空间,也就是说在一个.py文件中定义的标识符,但不在一个函数中。
第四层B(builtin),是指python解释器启动时就已经具有的命名空间,之所以叫builtin是因为在python解释器启动时会自动载入__builtin__模块,这个模块中的list、str等内置函数的就处于B层的命名空间中。

这三条规则通过一个例子来看比较明白。如下面例子所示:

>>> g = int('0x3', 0)
>>> def outFunc():
  e = 2
    g = 10
  def inFunc():
     l = 1
     return g + e
    return inFunc()
>>> outFunc() ===> 12

来详细看看这段代码中的标识符。
第1行,适用第一条规则“赋值产生标识符”,因此产生一个标识符g。“赋值的地点决定标识符所处的命名空间”,因为g是没有在一个函数定义中,因此g处于'G'层命名空间中。这一行中还有一个标识符,那就是int。那么int是在什么地方定义的呢?由于int是内置函数,是在__builtin__模块中定义的,所以int就处于'B'的层命名空间中。
第2行,适用第一条规则,由于def中包含一个隐性的赋值过程,这一行产生一个标识符outFunc,outFunc并不处于一个函数定义的内部,因此,outFunc处于'G'层命名空间中。此外,这一行还适用第二条规则,产生一个新的命名空间。
第3行,适用第一条规则,产生个标识符e,而且由于这是在一个函数定义内,并且内部还有函数定义,因此e处于'E'层命名空间中。
第4行要注意,适用第一条规则,产生一个标识符g,这个g与e一样外于'E'层命名空间中。这个g与第一行的g是不同的,因为所处的命名空间不一样。
第5行,适用第一条规则,产生一个处于'E'层命名空间的标识符inFunc。与第2行一样,这一行定义函数也产生一个新的命名空间。
第6行,适用第一条规则,产生一个标识符l,由于这个l处于一个函数内部,而且在这个函数内部没有其他函数的定义,因此l处于'L'层命名空间中。
第7行,适用第三条规则,python解释器首先看到标识符g,按照LEGB的顺序往上找,先找L层(也就是在inFunc内部),没有。再找E层,有,值为10。因此这里的g的值为10。寻找过程到为止,并不会再往上找到'G'层。寻找e的过程也一样,e的值为2。因此第9行的结果为12。

其实,所谓的“LEGB”是为了学术上便于表述而创造的。让一个编程的人说出哪个标识符处于哪个层没有什么意义,只要知道对于一个标识符,python是怎么寻找它的值的就可以了。其实找值的过程直观上也很容易理解。

通过上面的例子也可以看出,如果在不同的命名空间中定义了相同的标识符是没有关系的,并不会产生冲突。寻找一个标识符的值过程总是从当前层开始往上找的,首先找到的就为这个标识符的值。也由此可以这么说,'B'层标识符在所有模块(.py文件)中可用;'G'层标识符在当前模块内(.py文件)中可用;'E'和'L'层标识符在当前函数内可用。

再来看一个例子,来解释global语句的用法。代码如下所示:

>>> g = 'global'
>>> s = 'in'
>>> def out():
    g = 'out'
    def inter():
     global g     
     print s,g
  inter()
>>> out() ===> 'in global'

可以看到,虽然有两个层中的g,但使用了global语句后,就是指'G'层的标识符。也就是第7行中的g,就是指第1行产生的那个g,值为'global'。

最后说一句,其实只要在编程的时候注意一下,不要使用相同的标识符,基本上就可以避免任何与命名空间相关的问题。还有就是在一个函数中尽量不要使用上层命名空间中的标识符,如果一定要用,也最好使用参数传递的方式进行,这样有利于保持函数的独立性。

Python 相关文章推荐
Django如何配置mysql数据库
May 04 Python
Python获取航线信息并且制作成图的讲解
Jan 03 Python
基于PyQt4和PySide实现输入对话框效果
Feb 27 Python
Django中如何防范CSRF跨站点请求伪造攻击的实现
Apr 28 Python
pandas计数 value_counts()的使用
Jun 24 Python
python笔记_将循环内容在一行输出的方法
Aug 08 Python
Python使用matplotlib绘制Logistic曲线操作示例
Nov 28 Python
python中使用you-get库批量在线下载bilibili视频的教程
Mar 10 Python
Python3.7在anaconda里面使用IDLE编译器的步骤详解
Apr 29 Python
scrapy与selenium结合爬取数据(爬取动态网站)的示例代码
Sep 28 Python
Python 微信公众号文章爬取的示例代码
Nov 30 Python
解决python3.6用cx_Oracle库连接Oracle的问题
Dec 07 Python
Python判断变量是否已经定义的方法
Aug 18 #Python
Python实现全角半角转换的方法
Aug 18 #Python
Python实现冒泡,插入,选择排序简单实例
Aug 18 #Python
Python算法之栈(stack)的实现
Aug 18 #Python
Python实现partial改变方法默认参数
Aug 18 #Python
Python实现发送email的几种常用方法
Aug 18 #Python
Python内置数据类型详解
Aug 18 #Python
You might like
第十一节 重载 [11]
2006/10/09 PHP
PHP数据库操作之基于Mysqli的数据库操作类库
2014/04/19 PHP
非常实用的PHP常用函数汇总
2014/12/17 PHP
php查看网页源代码的方法
2015/03/13 PHP
PHP缓冲区用法总结
2016/02/14 PHP
php实现文件上传及头像预览功能
2017/01/15 PHP
PHP使用preg_split和explode分割textarea存放内容的方法分析
2017/07/03 PHP
PHP使用pdo实现事务处理操作示例
2018/09/05 PHP
JQuery 实现的页面滚动时浮动窗口控件
2009/07/10 Javascript
Javascript技巧之不要用for in语句对数组进行遍历
2010/10/20 Javascript
firefox下jquery iframe刷新页面提示会导致重复之前动作
2012/12/17 Javascript
js获取上传文件的绝对路径实现方法
2016/08/02 Javascript
Bootstrap Table服务器分页与在线编辑应用总结
2016/08/08 Javascript
JS制作类似选项卡切换的年历
2016/12/03 Javascript
Servlet3.0与纯javascript通过Ajax交互的实例详解
2018/03/18 Javascript
详解Webpack + ES6 最新环境搭建与配置
2018/06/04 Javascript
vue 属性拦截实现双向绑定的实例代码
2018/10/24 Javascript
ant design vue嵌套表格及表格内部编辑的用法说明
2020/10/28 Javascript
Python lxml模块安装教程
2015/06/02 Python
利用css3-animation实现逐帧动画效果
2016/03/10 HTML / CSS
新奇的小玩意:IWOOT
2016/07/21 全球购物
Space NK美国站:英国高端美妆护肤商城
2017/05/22 全球购物
荷兰的时尚市场:To Be Dressed
2019/05/06 全球购物
房屋租赁协议书
2014/04/10 职场文书
2014年教师节国旗下讲话稿
2014/09/10 职场文书
教师思想作风整顿个人剖析材料
2014/10/10 职场文书
2014年保育员工作总结
2014/12/02 职场文书
死者家属慰问信
2015/03/24 职场文书
2015年监理工作总结范文
2015/04/07 职场文书
检讨书怎么写
2015/05/07 职场文书
想创业成功,需要掌握这些要点
2019/12/06 职场文书
《语言的突破》读后感3篇
2019/12/12 职场文书
七年级作文之下雨天
2019/12/23 职场文书
nginx服务器的下载安装与使用详解
2021/08/02 Servers
Python干货实战之八音符酱小游戏全过程详解
2021/10/24 Python
python blinker 信号库
2022/05/04 Python