6.1. 关于 Modules 更多信息
module 就是python代码文件,可以放执行语句,变量定义和函数等. 注意这写语句仅在首次被导入的地方执行一次. [1]
每个module都有它私有的符号表, 可以被它里面定义的任何函数访问.
module可以导入其它modules. 也不必非得将import 语句放在module的开头. 被导入module的名字将被放到导入module的全局符号表中.
import支持将其它module中的符号直接导入到当前module的符号表中.例如:
>>> from main import test, aaa
>>> test()
TESTSSSSSSSSSSSSSSSSSSS
>>> aaa
1000
>>>
这时不会导入module名字 main.
import还支持导入module中所有符号(除以下划线开头 _ 的符号):
>>>frommainimport*
>>> test()
TESTSSSSSSSSSSSSSSSSSSS
>>> aaa
1000
>>>
注意,通常从一个module或package 中 import * 是危险的, 因为这样很容易让代码变得难以理解,同时可能导致不期望看到的符号覆盖.
注意基于效率考虑
, 对每次解析器会话每个module仅导入一次. 因此如果会话期间已导入的module发生了改变,就需要重启解析器–或者只是一个用于交互测试的module,使用 reload(modulename).
6.1.1. 将module作为脚本执行
python fibo.py
则module中的所有代码将被执行, 和在解析器中导入module一样, 但是有一点区别:
module执行上下全局变量中的 __name__ 被设置为 "__main__". 这就意味着将以下代码加到module的尾部:
if __name__ == "__main__":
import sys
main()
就可以将该代码文件既作为可导入的module使用,也可作为独立脚本使用。
1.2. Module 搜索路径
在执行 import spam 的时候, 解析器会依次在:
1). 存放当前执行脚本的目录下找;
2). 在环境变量
3).在编译安装python时确定的默认路径下找;
在Unix平台, 通常为 .:/usr/local/lib/python.
实际上, python 解析器搜索 module 的路径都放在 sys.path 中, 只是通常被初始化为以上 三种. 这就允许 Python 程序动态修改默认的查找路径.
注意: 存放当前运行脚本的目录为首次查找路径。 重要的一点是该脚本名字不能和标准 modules 中的任何一个重名. 察看 Standard Modules 章节获取更多信息.
6.1.3. 预编译的 Python 文件
为了加速运行导入了大量module的小程序, 如果在当前运行的 spam.py 存放目录下有一个叫做 spam.pyc 的文件存在, 则解析器会把它当作spam 模块已预编译的字节码版本.注意 spam.pyc 中记录着它对应的 spam.py 更改时间, 若spam.py 文件的modification time 和 .pyc 文件中的不一致,则该 .pyc 被忽略.
通常, 预编译 .pyc 字节码文件由解析器完成,你不必插手.
注意: .pyc 字节码文件是平***立的, 因此该文件可拷贝到不同架构的机器上使用.
其它专业的注意事项:当python解析器调用时使用了 -O 标志, 则会为运行脚本生成优化预编译字节码文件以.pyo结尾. 而不生成.pyc 文件.
如果python解析器调用时使用了两次 -O 标志,即 (-OO),将使得字节码编译器进行更深的优化以生成更紧凑的 .pyo 文件,注意有时可能会导致程序出问题.
注意预编译字节码机制生成的 .pyo 或 .pyc 文件只能用来提高程序被加载的速度,而不会提升程序的执行速.
从命令执行脚本时,解析器不会为它生成.pyc 或 .pyo 文件,在命令行时可通过通过预加载该module的代码或在命令行直接指定 .pyc 或 .pyo 文件来加速脚本的启动速度.
在发布你自己的python library 时使用 .pyc 或 .pyo 文件而不使用 .py 文件会让你的程序更难以反向工程.
模块 compileall 可以用来为指定目录下的所有 .py 文件生成 .pyc 或 .pyo 文件.