[转]Python-__builtin__与__builtins__的区别与关系(超详细,经典)
在学习Python时,很多人会问到__builtin__、__builtins__和builtins之间有什么关系。百度或Google一下,有很 多答案,但是这些答案要么不准确,要么只说了一点点,并不全面。本文将给大家一个较为全面的答案。以下结果是经过本人试验过的(测试环境:Linux Mint 14, Python2.7.3和Python3.2.3),并参考了Python的邮件列表。
在Python中,有一个内建模块,该模块中有一些常用函数;而该模块在Python启动后、且没有执行程序员所写的任何代码前,Python会首先加载 该内建函数到内存。另外,该内建模块中的功能可以直接使用,不用在其前添加内建模块前缀,其原因是对函数、变量、类等标识符的查找是按LE(N)GB法 则,其中B即代表内建模块。比如:内建模块中有一个abs()函数,其功能是计算一个数的绝对值,如abs(-20)将返回20。
在Python2.X版本中,内建模块被命名为__builtin__,而到了Python3.X版本中,却更名为builtins。
当使用内建模块中函数或其它功能时,可以直接使用,不用添加内建模块的名字;但是,如果想要向内建模块中添加一些功能,以便在任何函数中都能直接使用而不 用再进行import,这时,就要导入内建模块,在内建模块的命名空间(即__dict__字典属性)中添加该功能。在导入时,如果是Python2.X 版本,就要导入__builtin__模块;如果是Python3.X版本,就要导入builtins模块。如:在Python2.X中,向内建模块添加 一个函数(该函数打印“hello, world”),可以这样写(以下的用法是在主模块中的使用,其它模块请看下面):
import __builtin__
def print_hello():
print "hello, world"
__builtin__.__dict__['hello'] = print_hello
print_hello() # 将打印"hello, world"
hello() # 将打印"hello, world"
此时,print_hello和hello两个函数名几乎是一样,但是有一点区别,print_hello只能在该模块中使用,而hello可以在本程序中的其它任何一个模块中使用,因为hello已经放到内建模块中了。
现在,__builtin__和builtins之间的关系已经说清楚了,现在该说说__builtins__了。为了统一Python2.X和Python3.X,在下面的论述中,内建模块一律统称为__builtin__。
由上面的论述,我们知道,__builtin__存在于Python2.X中,而builtins存在于Python3.X中,但是对于 __builtins__,它却同时存在于Python2.X和Python3.X中。那么它到底是什么东西呢?由名字可知,它肯定与内建模块有关。其实 简单地说,它就是对内建模块一个引用。
1、__builtins__即是引用,那么它内建模块有一个相同点:Python程序一旦启动,它们二者就会在程序员所写的代码没有运行之前就已经被加载到内存中了。
2、虽是一个引用,但__builtins__和内建模块是有一点区别的:
(1)无论任何地方要想使用内建模块,都必须在该位置所处的作用域中导入__builtin__内建模块;而对于__builtins__却不用导入,它在任何模块都直接可见, 可以把它当作内建模块直接使用(这句并不完全正确,请看第(2)点)。即:__builtins__在任何地方、任何模块都可见,而内建模块名只在相应的 作用域中被import后才可以(该import并不是把内建模块加载到内存中——内建早已经被加载了,它仅仅是让内建模块名在该作用域中可见)。
(2)__builtins__虽是对内建模块的引用,但这个引用要看是使用__builtins__的模块是哪个模块:
1】 在主模块__main__中:
__builtins__是对内建模块__builtin__本身的引用,即__builtins__完全等价于__builtin__,二者完全是一个东西,不分彼此。它在任何地方都可见,即在任何地方都可使用它。此时,__builtins__的类型是模块类型。
__builtin__仅仅在导入它时才可见。哪个作用域中使用__builtin__,哪个作用域就要导入它(导入仅仅是让__builitin__标 识符在该作用域内可见)。一般都是在模块的顶层(即模块的全局作用域)导入__builtin__,这样,其后的任何作用域可通过标识符向上查找来引用 __builtin__。
2】在非__main__模块中:
__builtins__仅是对__builtin__.__dict__的引用,而非__builtin__本身。它在任何地方都可见。此时__builtins__的类型是字典。
__builtin__和在主模块中的情况一样。
由上面的异同,我们可以出,__builtins__、__builtin__和builtins之间并没有太大的不同;在使用__builtins__时,只要注意其引用的到底是__builtin__还是__builtin__.__dict__即可。
此时,可能会有人说,既然__builtin__和builtins由于Python版本的不同而不同,导致在写兼容2.X和3.X版本时的代码时比较麻 烦,而__builtins__在2.X和3.X中都是一样的,那么,不再使用builtins和__builin__,改用__builtins__不 是更好?!这种做法并没有错,但是有一点,在使用__builtins__时,要区分是在主模块__main__中,还是在其他的非__main__模块 中。笔者看了Python标准库(比如gettext),其中使用的是__builtin__(在Python2.X中)和builtins(在 Python3.X中),而并没有使用__builtins__。这仅仅给一些参考。
说明:
主模块__main__:在Python中,一个代码文件就是一个模块,一个模块就是一个代码文件;用来启动Python或者说首先执行的那个文件(相当 于C语言中main主函数所在的C文件)的模块名被Python命名为__main__,称为主模块,而对于其它被主模块或其他非主模块导入的模块,它们 的模块名则是文件名本身(除了后缀.py、.pyc或.pyo等)。每个模块都有一个名为__name__的属性,它表示着该模块的名字。除此之外,主模 块与其它非主模块之间还有一点区别,比如:from __future__ import absolute_import语句在非主模块中可以正常使用,反而在主模块中,好像没有什么效果——有等无。
[转]Python-__builtin__与__builtins__的区别与关系(超详细,经典)的更多相关文章
- Python-__builtin__与__builtins__的区别与关系(超详细,经典)(转)
Python-__builtin__与__builtins__的区别与关系(超详细,经典) (2013-07-23 15:27:32) 转载▼ 分类: Python 在学习Python时,很多人会 ...
- 【转】Python-__builtin__与__builtins__的区别与关系(超详细,经典)
在学习Python时,很多人会问到__builtin__.__builtins__和builtins之间有什么关系.百度或Google一下,有很 多答案,但是这些答案要么不准确,要么只说了一点点,并不 ...
- __builtin__与__builtins__的区别与关系
在学习Python时,很多人会问到__builtin__.__builtins__和builtins之间有什么关系.百度或Google一下,有很 多答案,但是这些答案要么不准确,要么只说了一点点,并不 ...
- Python __builtin__模块
你有没有好奇过当我们打开Python后就可以直接使用str(),list(),eval(),print(),max()这样的函数,而不用导入任何模块? 其实原因很简单,就是当我们打开Python解释器 ...
- ava、Python和PHP三者的区别
Java.Python和PHP三者的区别 2017年07月15日 22:09:21 书生_AABB 阅读数:18994 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blo ...
- python中// 和/有什么区别
python中// 和/有什么区别 通常C/C++中,"/ " 算术运算符的计算结果是根据参与运算的两边的数据决定的,比如: 6 / 3 = 2 ; 6,3都是整数,那么结果也就是 ...
- Python 2 和 3 的区别记录
Python 2 和 3 的区别记录 print 2:关键字,可以 print a,也可以 print(a) 3:内置函数,必须带(),print(a) reload() 2:内置函数,可以直接使用 ...
- Python中__repr__和__str__区别
Python中__repr__和__str__区别 看下面的例子就明白了 class Test(object): def __init__(self, value='hello, world!'): ...
- Java Web开发和Python Web开发之间的区别
今天的文章讨论了Java Web开发和Python Web开发之间的区别.我不鼓励我们在这里从Java Web迁移到Python Web开发.我只是想谈谈我的感受.它不一定适合所有情况,仅供我们参考. ...
随机推荐
- linux网络编程、系统编程
http://blog.csdn.net/lianghe_work/article/category/2871247
- if __name__=="__main__": 这个结尾的理解
print "别人应用我做为模块导入,就只看到我" if __name__=="__main__": print "自己文件执行就看到我输出" ...
- 建立SIP通话
建立SIP: 点击下的出现的页面: 选择submit,只用填写用户名和密码就OK了,secret是密码,填写完以后记得应用 创建完毕以后,使用xlite去连接:xlite的配置:域名是asterisk ...
- 福利向:几款给力的Unity脚本插件推荐
转自:http://www.gamelook.com.cn/2016/09/264877 Unity的Asset Store中除了拥有非常强大的Unity编辑器扩展工具之外,还有一些让开发过程事半功倍 ...
- 5月11日上课笔记-js简介
一.js 1.javascript简介: 是一门脚本语言(弱类型编程语言)(php是脚本语言) 编程语言如java,先编译后运行 脚本语言不需要编译 作用: 表单验证 页面特效 语法:和Java类似, ...
- 【UVa】11212 Editing a Book(IDA*)
题目 题目 分析 get一下IDA*的技巧,感觉总体来说不难,主要是剪枝比较难想. 这是lrj的代码,比较通俗易懂,关键就是选定一个区间再取出来,插入到一个位置,接下来转移到这个状态. ...
- 第一个 Windows 界面程序
编译器 使用的编译器为 Visual Studio 2017 菜单栏 -> 文件 -> 新建 -> 项目 选择 Windows 桌面应用程序,然后填好相关信息后点击“确定” 在解决方 ...
- Python Twisted系列教程21: Twisted和Haskell
作者:dave@http://krondo.com/twisted-and-haskell/ 译者: Cheng Luo 你可以从”第一部分 Twist理论基础“开始阅读:也可以从”Twisted ...
- 局部加权线性回归(Locally weighted linear regression)
首先我们来看一个线性回归的问题,在下面的例子中,我们选取不同维度的特征来对我们的数据进行拟合. 对于上面三个图像做如下解释: 选取一个特征,来拟合数据,可以看出来拟合情况并不是很好,有些数据误差还是比 ...
- Python Tkinter编程
声明:主要是为了自己方便,所以把别人的教程搬到这里来,没有其他的意思. 如果有侵犯您的权益,请联系我QQ:3121922008 我会在第一时间妥善处理,抱歉. 还有其他的一些搜集的资源连接放在http ...