什么是模块
- 模块支持从逻辑上组织python代码
- 把其他模块中的属性添加到你自己模块重点操作就是import
- 那些自我包含并且有组织的代码片段就是模块
模块与文件
文件是物理层面上组织模块的方法,模块名字就是对应文件名字去掉.py后缀。
模块名称空间
同名情况下,属性之间可以通过句点属性标识各自的模块名称空间,以免混淆。
搜索路径与路径搜索
- 搜索路径是一个路径的集合(sys.path 可以查看当前搜索路径)
- 路径搜索是一个行为,在导入模块的时候会去搜索路径查找的过程
名称空间
一个名称空间就是一个从名称到对象的关系映射集合。
代码执行期间有三个名称空间:局部名称空间,全局名称空间,内建名称空间。
局部名称空间在执行时是在不断变化的。
名称空间与变量作用域比较
名称空间是纯粹意义上的名字和对象间的映射关系,而作用域指出了从用户代码的哪些物理位置可以访问到这些名字。
名称空间及变量作用域
名称查找、确定作用域、覆盖
访问一个属性时,首先从局部名称空间开始,没找到则继续查找全局名称空间,再查找失败则在内建名称空间查找。同名情况下,前者会覆盖后者。
def foo():
bar = 2
print "in foo(), bar is {}".format(bar)
bar = 1
foo()
print 'in __main__, bar is {}'.format(bar)
上述代码Output:
in foo(), bar is 2
in __main__, bar is 1
导入模块
import语句
- 导入顺序建议(用空行区分):
- python标准库模块
- python第三方模块
- 应用程序自定义模块
- from-import语句,可以导入模块中的指定属性
- 多行导入,eg: from Tkinter import (TK, Frame, Button, Canvas)
- 扩展的import语句(as),eg: import Tkinter as tk
模块导入的特性
- 载入时执行模块,模块第一次导入时会被加载执行,后续再导入不再加载执行。
- 被导入到导入者作用域的名字
imptee.py
foo = 'abc'
def show():
print 'foo from imptee: ', foo
impter.py
from imptee import foo, show
show()
foo = 123
print 'foo from impter:', foo
show()
Output:
foo from imptee: abc
foo from impter: 123
foo from imptee: abc
impter.py
import imptee
imptee.show()
imptee.foo = 123
print 'foo from impter:', imptee.foo
show()
Output:
foo from imptee: abc
foo from impter: 123
foo from imptee: 123
__future__
Python提供了__future__
模块,把下一个新版本的特性导入到当前版本
需要使用from __future__ import new_feature
的形式来使用新特性比如除法新特性是返回浮点数的,而不是整除。
from __future__ import division
print '10 / 3 =', 10 / 3
print '10.0 / 3 =', 10.0 / 3
print '10 // 3 =', 10 // 3
Output:
10 / 3 = 3.33333333333
10.0 / 3 = 3.33333333333
10 // 3 = 3
从zip文件中导入模块
搜索路径中存在一个包含Python模块(.py,.pyc,.pyo)的.zip文件,导入时汇报ZIP文件当做目录处理。
globals() 和 locals()
globals() 和 locals()这两个内建函数分别返回调用者全局和局部名称空间的字典。
在全局名称空间下,两个函数返回结果一致。但在函数中就各不相同了。
reload()
这个内建函数可以重新导入加载一个已经导入的模块。前提是之前有过导入模块。
eg: reload(sys) (要确保之前有import sys)
一般模块是在第一次导入时执行一次,以后再import就不再执行,仅仅绑定模块名称。但reload()函数不同,仍然执行。
包
包是有层次的目录结构,1.5后加入了包,主要用来解决下面问题:
- 为平坦的名称空间加入有层次的组织结构
- 可以使有联系的模块放在一起
- 使用目录结构优于一堆混乱的文件
- 解决模块名称冲突
通过句点属性标识来访问包的元素。
需要注意文件夹下得有个__init__.py
文件,该文件可以空白。也可以填写内容提供功能:
- 如
__all__=['a', 'b']
可以表明包仅仅允许a,b模块被导入。 - import module 可以在这里导入一些模块,这样可以通过导入本包来导入这个module。
绝对导入与相对导入
- 绝对导入:
包使用越来越广泛,很容易子包跟标准模块名字冲突。
包模块会把名字相同的标准库隐藏掉,因为它首先在包内执行相对导入。
2.7后绝对导入特性是默认功能。
- 相对导入
语法关键是首部多了个句点.。其后多出一个句点表示当前from查找位置的更上层目录。
现在大项目基本都是提倡使用绝对导入比较好,简单明了。
个人小脚本书写可以通过用..表示上级目录来进行性对导入。eg: from ..Fax import G3.dial
关键是在于执行环境是处于哪个路径,这个路径就是搜索路径中的第一个路径,绝对import就是按照这个路径而言的绝对路径来导入模块,而相对导入则是按照规则在一个.后面来处理查找到该文件相对路径来导入模块
注意:
所谓的给sys.path加路径实际上是增加搜索路径,这个跟相对导入无关,它只是可能会涉及把相对路径加到搜索路径里而已。
相对导入时指 from .Fax import module 或者from ..Fax import module这种形式的导入方式。
- 自动加载模块,
__builtin__
里面的模块都是自动加载的 - 属性名称前加一个
_
,这样在from module import * 的情况下不会被导入。但是仍然可以指定from module import _a 这样导入
网友评论