1. 概述
模块有点类似 C++ 中的 Namespace,但并不完全相同
2. 导入模块
通过使用 import
语句来导入一个模块进行使用
1 | #!/usr/bin/python |
在上面的例子中,通过使用
import sys
就可以通过sys.function
的形式来调用 sys 模块中的函数和变量。
用户自定义模块在第一次导入时,会编译成字节码文件,这是 Python 处理的,可以提高模块导入的效率。
这些文件以.pyc
为扩展名,如果 Python 没有当前目录的访问权限,那么就不会创建.pyc
文件
第三方模块可以通过 Python 自带的
pip
进行安装
另外,还可以通过使用 from...import...
语句来导入语句;
它和 import
语句的唯一区别就是在模块导入之后,不用再在调用的时候填写模块名称。
1 | # Import statement |
注意,
from...import *
语句不会导入以双下划线开头的标识符,如__version__
一般来说,不建议使用
from...import...
语句
3. 创建模块
创建模块最简单的方法就是编写 .py 文件;
一个 .py
文件就是一个 Python 模块。
例如:
1 | #!/usr/bin/python |
Module Demo:
1 | #!/usr/bin/python |
4. 模块的默认变量
每个模块都有几个默认变量,它们是由 Python 自动构建的;
如 __name__
变量,这是模块的名字(即 .py
文件的名字)
可以使用 __name__
变量来检测其自身是否是作为主程序运行
1 | #!/usr/bin/python |
'__main__'
是主模块的名字,也就是主程序的文件名
5. dir()
函数
dir()
函数是内建函数,可以通过它来列出模块定义的标识符,包括函数、类和变量
如果不提供参数,则返回当前模块中定义的名称列表
1 | 1, 2, 3, 4, 5] a = [ |
由此可以看出,主模块具有
__buitins__
对象,实际上这就是 Python 的内建函数和类
dir()
函数一般不会将内建函数列出,如果需要查看,可以通过dir(builtins)
查看
6. 包(Package)
包是模块的文件夹,其中包含了很多模块;
同时一个包也可以包含另一个包。
一个包必须包含 __init__.py
文件,以免 Python 将包识别为普通目录
可以使用点号来访问到包中的模块
例如:
1 | sound/ Top-level package |
关于
__init__.py
:
- 一个包必须包含这个文件
- 这个文件可以是空的,也可以做一些包的初始化工作,比如定义
__all__
变量
6.1 导入包
包的导入有如下几种形式:
-
使用
import
语句例如
import sound.effects.echo
, 将sound/effects/echo
模块导入;
使用方法为sound.effects.echo.echofilter(input, output, delay = 0.7, atten = 4
-
使用
from package import item
在包(Package)层面,Python 推荐这么导入,主要的优点在于能够减少没有必要的前缀修饰。
例如:from sound.effects import echo
将echo
模块导入
使用方法为:echo.echofilter(input, output, delay = 0.7, atten = 4)
-
补充:关于
from package import *
和__all__
变量__all__
变量通常在__init__.py
文件中定义,用于指定允许import *
识别的标识符,即允许导出的标识符;
如果没有指定这个变量,那么在使用import *
时便会自动忽略以下划线开头的标识符 -
内包导入
对于包中的模块,在可能需要到另一个兄弟包模块的时候,由于它们处在同一个目录结构中,所以可以简单地省略一些前缀。
Python 在导入包时,首先会搜寻当前目录,如果搜索不到,则再到系统 PATH 中进行搜索
例如srround
想要利用echo
模块,则直接简单地import echo
即可。在 Python 2.5 之后,可以使用相对路径进行包导入,例如:
1
2
3
4
5# 一个点代表当前目录
# 两个点代表父目录
from . import echo
from .. import formats
from ..filters import equalizer
目前,Python 推荐使用
from package import item
的包层面导入,和import module
的模块层面导入方法,能更好地避免冗余和变量名称冲突。