您的位置:首页 > 编程语言 > Python开发

python学习10-模块

2016-05-27 09:50 429 查看
模块

模块是用来组织 Python 代码的方法, 而包则是用来组织模块的。这些代码段是共享的,所以Python 允许 “调入” 一个模块, 允许使用其他模块的属性来利用之前的工作成果, 实现代码重用.这个把其他模块中属性附加到你的模块中的操作叫做导入(import) 。那些自我包含并且有组织的代码片断就是模块( module )。

模块名称空间

从基本概念来说, 一个名称空间就是一个从名称到对象的关系映射集合。给定一个模块名之后, 只可能有一个模块被导入到 Python 解释器中, 所以在不同模块间不会出现名称交叉现象; 所以每个模块都定义了它自己的唯一的名称空间。

默认搜索路径是在编译或是安装时指定的。 它可以在一个或两个地方修改。

一个是启动 Python 的 shell 或命令行的 PYTHONPATH 环境变量。 该变量的内容是一组用冒号分割的目录路径。 如果你想让解释器使用这个变量, 那么请确保在启动解释器或执行 Python 脚本前设置或修改了该变量。解释器启动之后, 也可以访问这个搜索路径, 它会被保存在 sys 模块的 sys.path 变量里。不过它已经不是冒号分割的字符串, 而是包含每个独立路径的列表。

如果你知道你需要导入的模块是什么,而它的路径不在搜索路径里, 那么只需要调用列表的 append() 方法即可, 就像这样:

sys.path.append(‘/home/wesc/py/lib’)

修改完成后, 你就可以加载自己的模块了。 只要这个列表中的某个目录包含这个文件, 它就会被正确导入。 当然, 这个方法是把目录追加在搜索路径的尾部。 如果你有特殊需要, 那么应该使用列表的 insert() 方法操作 。

名称空间

名称空间是名称(标识符)到对象的映射。 向名称空间添加名称的操作过程涉及到绑定标识符到指定对象的操作.改变一个名字的绑定叫做重新绑定, 删除一个名字叫做解除绑定。

执行期间有两个或三个活动的名称空间。 这三个名称空间分别是局部名称空间, 全局名称空间和内建名称空间, 但局部名称空间在执行期间是不断变化的, 所以我们说”两个或三个”。 从名称空间中访问这些名字依赖于它们的加载顺序, 或是系统加载这些名称空间的顺序。

builtinsbuiltin

builtins 模块和 builtin 模块不能混淆。 虽然它们的名字相似——尤其对于新手来说。 builtins 模块包含内建名称空间中内建名字的集合。 其中大多数(如果不是全部的话)来自 builtin 模块, 该模块包含内建函数, 异常以及其他属性。 在标准 Python 执行环境下,builtins 包含 builtin 的所有名字。

名称空间与变量作用域比较

名称空间是纯粹意义上的名字和对象间的映射关系, 而作用域还指出了从用户代码的哪些物理位置可以访问到这些名字。

注意每个名称空间是一个自我包含的单元。但从作用域的观点来看, 事情是不同的. 所有局部名称空间的名称都在局部作用范围内。局部作用范围以外的所有名称都在全局作用范围内。还要记得在程序执行过程中, 局部名称空间和作用域会随函数调用而不断变化, 而全局名称空间是不变的。

名称查找, 确定作用域, 覆盖

那么确定作用域的规则是如何联系到名称空间的呢? 它所要做的就是名称查询. 访问一个属性时, 解释器必须在三个名称空间中的一个找到它。 首先从局部名称空间开始, 如果没有找到, 解释器将继续查找全局名称空间. 如果这也失败了, 它将在内建名称空间里查找。 如果最后的尝试也失败了, 你会得到错误

无限制的名称空间

Python 的一个有用的特性在于你可以在任何需要放置数据的地方获得一个名称空间。 我们已经在前一章见到了这一特性, 你可以在任何时候给函数添加属性(使用熟悉的句点属性标识)。

import 语句的模块顺序

我们推荐所有的模块在 Python 模块的开头部分导入。 而且最好按照这样的顺序:

z Python 标准库模块

z Python 第三方模块

z 应用程序自定义模块

from-import 语句

你可以在你的模块里导入指定的模块属性。 也就是把指定名称导入到当前作用域。 使用from-import 语句可以实现我们的目的, 它的语法是:

from module import name1[, name2[,… nameN]]

解释器执行到这条语句, 如果在搜索路径中找到了指定的模块, 就会加载它。该过程遵循作用域原则, 如果在一个模块的顶层导入, 那么它的作用域就是全局的; 如果在函数中导入, 那么它的作用域是局部的。如果模块是被第一次导入, 它将被加载并执行。

载入时执行模块

加载模块会导致这个模块被”执行”。 也就是被导入模块的顶层代码将直接被执行。 这通常包括设定全局变量以及类和函数的声明。 如果有检查 name 的操作, 那么它也会被执行。

导入到当前名称空间的名称

调用 from-import 可以把名字导入当前的名称空间里去, 这意味着你不需要使用属性/句点属性标识来访问模块的标识符。 例如, 你需要访问模块 module 中的 var 名字是这样被导入的:

from module import var

我们使用单个的 var 就可以访问它自身。 把 var 导入到名称空间后就再没必要引用模块了。当然, 你也可以把指定模块的所有名称导入到当前名称空间里:

from module import *

导入(import )和加载(load) 一个模块只被加载一次, 无论它被导入多少次。

被导入到导入者作用域的名字

只从模块导入名字的另一个副作用是那些名字会成为局部名称空间的一部分。 这可能导致覆盖一个已经存在的具有相同名字的对象。 而且对这些变量的改变只影响它的局部拷贝而不是所导入模块的原始名称空间。 也就是说, 绑定只是局部的而不是整个名称空间。

从 ZIP 文件中导入模块

Python 加入了从 ZIP 归档文件导入模块的功能。 如果你的搜索路径中存在一个包含 Python 模块(.py, .pyc, or .pyo 文件)的 .zip 文件, 导入时会把 ZIP 文件当作目录处理, 在文件中搜索模块。

模块内建函数

Python 1.5 加入了 import() 函数, 它作为实际上导入模块的函数, 这意味着 import 语句调用 import() 函数完成它的工作。提供这个函数是为了让有特殊需要的用户覆盖它, 实现自定义的导入算法。

globals() 和 locals()

globals() 和 locals() 内建函数分别返回调用者全局和局部名称空间的字典。 在一个函数内部, 局部名称空间代表在函数执行时候定义的所有名字, locals() 函数返回的就是包含这些名字的字典。 globals() 会返回函数可访问的全局名字。

reload()

reload() 内建函数可以重新导入一个已经导入的模块。 它的语法如下:

reload(module)

module 是你想要重新导入的模块。使用 reload() 的时候有一些标准。 首先模块必须是全部导入(不是使用 from-import), 而且它必须被成功导入。另外 reload() 函数的参数必须是模块自身而不是包含模块名的字符串。 也就是说必须类似 reload(sys) 而不是 reload(‘sys’)。模块中的代码在导入时被执行, 但只执行一次. 以后执行 import 语句不会再次执行这些代码,只是绑定模块名称。 而 reload() 函数不同。



包是一个有层次的文件目录结构, 它定义了一个由模块和子包组成的 Python 应用程序执行环境。Python 1.5 加入了包, 用来帮助解决如下问题:

z 为平坦的名称空间加入有层次的组织结构

z 允许程序员把有联系的模块组合到一起

z 允许分发者使用目录结构而不是一大堆混乱的文件

z 帮助解决有冲突的模块名称

与 类 和 模 块 相 同 , 包 也 使 用 句 点 属 性 标 识 来 访 问 他 们 的 元 素 。 使 用 标 准 的 import 和from-import 语句导入包中的模块

你也可使用 from-import 实现不同需求的导入。

第一种方法是只导入顶层的子包, 然后使用属性/点操作符向下引用子包树:

from Phone import Mobile

Mobile.Analog.dial(‘555-1212’)

此外, 我们可以还引用更多的子包:

from Phone.Mobile import Analog

Analog.dial(‘555-1212’)

事实上, 你可以一直沿子包的树状结构导入:

from Phone.Mobile.Analog import dial

dial(‘555-1212’)

使用 from-import 导入包

包同样支持 from-import all 语句:

from package.module import *

然而, 这样的语句会导入哪些文件取决于操作系统的文件系统. 所以我们在init.py 中加入 all 变量. 该变量包含执行这样的语句时应该导入的模块的名字. 它由一个模块名字符串列表组成.。

绝对导入

包的使用越来越广泛, 很多情况下导入子包会导致和真正的标准库模块发生(事实上是它们的名字)冲突。 包模块会把名字相同的标准库模块隐藏掉, 因为它首先在包内执行相对导入, 隐藏掉标准库模块。

相对导入

语法的第一部分是一个句点, 指示一个相对的导入操作。 之后的其他附加句点代表当前 from起始查找位置后的一个级别。

自动载入的模块

当 Python 解释器在标准模式下启动时, 一些模块会被解释器自动导入, 用于系统相关操作唯一一个影响你的是 builtin 模块, 它会正常地被载入, 这和 builtins 模块相同。sys.modules 变量包含一个由当前载入(完整且成功导入)到解释器的模块组成的字典, 模块名作为键, 它们的位置作为值。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  python