chap 12 模块和文件
1. 模块
当代码量变得相当大的时候, 我们最好把代码分成一些有组织的代码段,前提是保证它们的彼此交互。 这些代码片段相互间有一定的联系, 可能是一个包含数据成员和方法的类, 也可能是一组相关但彼此独立的操作函数。 这些代码段是共享的,所以Python 允许 "调入" 一个模块, 允许使用其他模块的属性来利用之前的工作成果, 实现代码重用.
这个把其他模块中属性附加到你的模块中的操作叫做导入(import) 。那些自我包含并且有组织的代码片断就是模块( module )。
2. 模块名称空间
模块的一个名称空间就是一个从名称到对象的关系映射集合。每个模块都定义了它自己的唯一的名称空间。给定一个模块名之后, 只可能有一个模块被导入到 Python 解释器中, 所以在不同模块间不会出现名称交叉现象。
3. 搜索路径和路径搜索
搜索路径是指查找某个文件的操作,路径搜索指去查找一组目录。如果你知道你需要导入的模块是什么,而它的路径不在搜索路径里, 那么只需要调用列表的 append() 方法即可,比如sys.path.append('/home/wesc/py/lib')。使用sys.modules返回一个字典,从中可以找到当前导入了哪些模块和它们来自什么地方。
4. 名称空间和变量作用域
访问一个属性时, 解释器必须在三个名称空间中的一个找到它。 首先从局部名称空间开始, 如果没有找到, 解释
器将继续查找全局名称空间. 如果这也失败了, 它将在内建名称空间里查找。 如果最后的尝试也失败了, 你会得到NameError的错误
python可以随意地在任何需要放置数据的地方获得一个名称空间。
比如你可以在任何时候给函数添加属性:
def foo():
pass
foo.__doc__ = 'Oops, forgot to add doc str above!'
foo.version = 0.2
还可以对类添加实例属性。
class MyUltimatePythonStorageDevice(object):
pass
bag = MyUltimatePythonStorageDevice()
bag.x = 100
bag.y = 200
bag.version = 0.1
bag.completed = False
5. 导入模块 关键字import
a.推荐导入的顺序:标准库模块,第三方模块,应用程序自定义模块
b.from module import attributeName1,[attributeName2[,...sttributeNameN]]
c.如果使用多行导入的话,需要在行尾添加反斜杠\
d.import ..as..用自己想要的名字替换模块的原始名称。 比如说import Tkinter as tk
6. 模块导入的特性
a.载入时执行模块,也就是被导入模块的顶层代码将直接被执行。这通常包括设定全局变量以及类和函数的声明。 如果有检查 __name__ 的操作, 那么它也会被执行。所以设计模块时,应把尽可能多的代码封装到函数中。要养成只把函数和模块定义放入模块的顶层的好习惯。
b.限制使用from module import *,谨慎使用,如果要导入某个模块的变量很多,那么可以选择使用
c.只从模块导入名字的另一个副作用是那些名字会成为局部名称空间的一部分。 这可能导致覆盖一个已经存在的具有相同名字的对象。 而且对这些变量的改变只影响它的局部拷贝而不是所导入模块的原始名称空间。 也就是说, 绑定只是局部的而不是整个名称空间。解决方法:使用 import 和完整的标识符名称(句点属性标识)
d.python还可以从zip归档文件中导入模块
e.globals() 和 locals() 内建函数分别返回调用者全局和局部名称空间的字典。
f.reload()重新导入一个已经导入的模块。一般来讲代码在导入的时候被执行,且只执行一次,以后重复执行import语句时,就不再执行这些代码,而是绑定模块名称,而reload()则不同于一般情况,它在重载模块时会再次执行代码。
7. 包
包是一个有层次的文件目录结构, 它定义了一个由模块和子包组成的 Python 应用程序执行环境。与类和模块相同,包也使用句点属性标识来访问他们的元素。使用标准的import和from-import语句导入包中的模块。
我们可以根据包的树形结构来访问包中的子包或者属性。使用from-import导入的时候会使用到__init.py__文件,这是初始化模块,比如from package.module import *,这样的语句会根据操作系统的文件系统导入哪些文件,此时可以在__init.py__中设置__all__变量来设置应该导入的模块的名字
8. 模块的其他特性
自动载入的模块__builtin__和__builtins__,通过sys.modules可以看出当前导入的模块的名称以及所在位置
阻止性导入,在模块属性之前加上_下划线。比如import foo._bar
1. 模块
当代码量变得相当大的时候, 我们最好把代码分成一些有组织的代码段,前提是保证它们的彼此交互。 这些代码片段相互间有一定的联系, 可能是一个包含数据成员和方法的类, 也可能是一组相关但彼此独立的操作函数。 这些代码段是共享的,所以Python 允许 "调入" 一个模块, 允许使用其他模块的属性来利用之前的工作成果, 实现代码重用.
这个把其他模块中属性附加到你的模块中的操作叫做导入(import) 。那些自我包含并且有组织的代码片断就是模块( module )。
2. 模块名称空间
模块的一个名称空间就是一个从名称到对象的关系映射集合。每个模块都定义了它自己的唯一的名称空间。给定一个模块名之后, 只可能有一个模块被导入到 Python 解释器中, 所以在不同模块间不会出现名称交叉现象。
3. 搜索路径和路径搜索
搜索路径是指查找某个文件的操作,路径搜索指去查找一组目录。如果你知道你需要导入的模块是什么,而它的路径不在搜索路径里, 那么只需要调用列表的 append() 方法即可,比如sys.path.append('/home/wesc/py/lib')。使用sys.modules返回一个字典,从中可以找到当前导入了哪些模块和它们来自什么地方。
4. 名称空间和变量作用域
访问一个属性时, 解释器必须在三个名称空间中的一个找到它。 首先从局部名称空间开始, 如果没有找到, 解释
器将继续查找全局名称空间. 如果这也失败了, 它将在内建名称空间里查找。 如果最后的尝试也失败了, 你会得到NameError的错误
python可以随意地在任何需要放置数据的地方获得一个名称空间。
比如你可以在任何时候给函数添加属性:
def foo():
pass
foo.__doc__ = 'Oops, forgot to add doc str above!'
foo.version = 0.2
还可以对类添加实例属性。
class MyUltimatePythonStorageDevice(object):
pass
bag = MyUltimatePythonStorageDevice()
bag.x = 100
bag.y = 200
bag.version = 0.1
bag.completed = False
5. 导入模块 关键字import
a.推荐导入的顺序:标准库模块,第三方模块,应用程序自定义模块
b.from module import attributeName1,[attributeName2[,...sttributeNameN]]
c.如果使用多行导入的话,需要在行尾添加反斜杠\
d.import ..as..用自己想要的名字替换模块的原始名称。 比如说import Tkinter as tk
6. 模块导入的特性
a.载入时执行模块,也就是被导入模块的顶层代码将直接被执行。这通常包括设定全局变量以及类和函数的声明。 如果有检查 __name__ 的操作, 那么它也会被执行。所以设计模块时,应把尽可能多的代码封装到函数中。要养成只把函数和模块定义放入模块的顶层的好习惯。
b.限制使用from module import *,谨慎使用,如果要导入某个模块的变量很多,那么可以选择使用
c.只从模块导入名字的另一个副作用是那些名字会成为局部名称空间的一部分。 这可能导致覆盖一个已经存在的具有相同名字的对象。 而且对这些变量的改变只影响它的局部拷贝而不是所导入模块的原始名称空间。 也就是说, 绑定只是局部的而不是整个名称空间。解决方法:使用 import 和完整的标识符名称(句点属性标识)
d.python还可以从zip归档文件中导入模块
e.globals() 和 locals() 内建函数分别返回调用者全局和局部名称空间的字典。
f.reload()重新导入一个已经导入的模块。一般来讲代码在导入的时候被执行,且只执行一次,以后重复执行import语句时,就不再执行这些代码,而是绑定模块名称,而reload()则不同于一般情况,它在重载模块时会再次执行代码。
7. 包
包是一个有层次的文件目录结构, 它定义了一个由模块和子包组成的 Python 应用程序执行环境。与类和模块相同,包也使用句点属性标识来访问他们的元素。使用标准的import和from-import语句导入包中的模块。
我们可以根据包的树形结构来访问包中的子包或者属性。使用from-import导入的时候会使用到__init.py__文件,这是初始化模块,比如from package.module import *,这样的语句会根据操作系统的文件系统导入哪些文件,此时可以在__init.py__中设置__all__变量来设置应该导入的模块的名字
8. 模块的其他特性
自动载入的模块__builtin__和__builtins__,通过sys.modules可以看出当前导入的模块的名称以及所在位置
阻止性导入,在模块属性之前加上_下划线。比如import foo._bar