详细介绍 Python-__builtin__与__builtins__和builtins的区别与关系

2024-01-29 21:32

本文主要是介绍详细介绍 Python-__builtin__与__builtins__和builtins的区别与关系,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

在学习Python时,很多人会问到__builtin__、__builtins__和builtins之间有什么关系。百度或Google一下,有很多答案,但是这些答案要么不准确,要么只说了一点点,并不全面。本文将给大家一个较为全面的答案。以下结果是经过本人试验过的(测试环境:LinuxMint 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__

defprint_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__ importabsolute_import语句在非主模块中可以正常使用,反而在主模块中,好像没有什么效果——有等无。

这篇关于详细介绍 Python-__builtin__与__builtins__和builtins的区别与关系的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/658236

相关文章

电脑密码怎么设置? 一文读懂电脑密码的详细指南

《电脑密码怎么设置?一文读懂电脑密码的详细指南》为了保护个人隐私和数据安全,设置电脑密码显得尤为重要,那么,如何在电脑上设置密码呢?详细请看下文介绍... 设置电脑密码是保护个人隐私、数据安全以及系统安全的重要措施,下面以Windows 11系统为例,跟大家分享一下设置电脑密码的具体办php法。Windo

JSON字符串转成java的Map对象详细步骤

《JSON字符串转成java的Map对象详细步骤》:本文主要介绍如何将JSON字符串转换为Java对象的步骤,包括定义Element类、使用Jackson库解析JSON和添加依赖,文中通过代码介绍... 目录步骤 1: 定义 Element 类步骤 2: 使用 Jackson 库解析 jsON步骤 3: 添

将sqlserver数据迁移到mysql的详细步骤记录

《将sqlserver数据迁移到mysql的详细步骤记录》:本文主要介绍将SQLServer数据迁移到MySQL的步骤,包括导出数据、转换数据格式和导入数据,通过示例和工具说明,帮助大家顺利完成... 目录前言一、导出SQL Server 数据二、转换数据格式为mysql兼容格式三、导入数据到MySQL数据

Redis的Zset类型及相关命令详细讲解

《Redis的Zset类型及相关命令详细讲解》:本文主要介绍Redis的Zset类型及相关命令的相关资料,有序集合Zset是一种Redis数据结构,它类似于集合Set,但每个元素都有一个关联的分数... 目录Zset简介ZADDZCARDZCOUNTZRANGEZREVRANGEZRANGEBYSCOREZ

Python判断for循环最后一次的6种方法

《Python判断for循环最后一次的6种方法》在Python中,通常我们不会直接判断for循环是否正在执行最后一次迭代,因为Python的for循环是基于可迭代对象的,它不知道也不关心迭代的内部状态... 目录1.使用enuhttp://www.chinasem.cnmerate()和len()来判断for

使用Python实现高效的端口扫描器

《使用Python实现高效的端口扫描器》在网络安全领域,端口扫描是一项基本而重要的技能,通过端口扫描,可以发现目标主机上开放的服务和端口,这对于安全评估、渗透测试等有着不可忽视的作用,本文将介绍如何使... 目录1. 端口扫描的基本原理2. 使用python实现端口扫描2.1 安装必要的库2.2 编写端口扫

使用Python实现操作mongodb详解

《使用Python实现操作mongodb详解》这篇文章主要为大家详细介绍了使用Python实现操作mongodb的相关知识,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录一、示例二、常用指令三、遇到的问题一、示例from pymongo import MongoClientf

使用Python合并 Excel单元格指定行列或单元格范围

《使用Python合并Excel单元格指定行列或单元格范围》合并Excel单元格是Excel数据处理和表格设计中的一项常用操作,本文将介绍如何通过Python合并Excel中的指定行列或单... 目录python Excel库安装Python合并Excel 中的指定行Python合并Excel 中的指定列P

四种Flutter子页面向父组件传递数据的方法介绍

《四种Flutter子页面向父组件传递数据的方法介绍》在Flutter中,如果父组件需要调用子组件的方法,可以通过常用的四种方式实现,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录方法 1:使用 GlobalKey 和 State 调用子组件方法方法 2:通过回调函数(Callb

一文详解Python中数据清洗与处理的常用方法

《一文详解Python中数据清洗与处理的常用方法》在数据处理与分析过程中,缺失值、重复值、异常值等问题是常见的挑战,本文总结了多种数据清洗与处理方法,文中的示例代码简洁易懂,有需要的小伙伴可以参考下... 目录缺失值处理重复值处理异常值处理数据类型转换文本清洗数据分组统计数据分箱数据标准化在数据处理与分析过