为了提高调用许多标准Python模块的小程序的启动时间,一个重要的措施是,如果在找到“spam.py ”的目录中存在一个名为“spam.pyc”的文件,就认为此文件包含了模块spam的一个所谓“ 字节编译”版本。
用于生成“spam.pyc”的“spam.py”的修改时间被记入了“spam.pyc”中,如果记录的修改时间与现在文件的时间不相符的话就忽略编译文件。一般不需要自己生成“spam.pyc”这样的编译文件。每当“spam.py”成功编译后解释程序就尝试写编译版本“spam.pyc”,如果不可写也不会出错;#t#
如果因为某种原因此文件没有写完则生成的“spam.pyc”被识别为不完整的而被忽略。编译文件“spam.pyc”的格式是不依赖于平台的,所以不同结构的机器可以共享Python模块目录。
下面是对专家的一些窍门:
如果Python解释程序是以-O标志启动的,将生成优化的编译代码,保存在“.pyo”文件中。目前优化不是很多,现在只是去掉assert语句和SET_LINENO指令。使用了-O标志时,所有字节码都是优化的,“.pyc”文件被忽略,“.py”文件被编译为优化的字节码。 给Python解释程序两个优化标志(-OO)产生的优化代码有时会导致程序运行不正常。
目前双重优化只从字节码中删除了__doc__字符串,使得“.pyo”文件较小。有些程序可能是依赖于文档字符串的,所以只有在确知不会有问题时才可以使用这样的优化。 从“.pyc”或“.pyo”读入的程序并不能比从“.py”读入的运行更快,它们只是调入速度更快一些。 如果一个程序是用在命令行指定脚本文件名的方式运行的。
脚本的字节码不会写入“.pyc ”或“.pyo”文件。所以如果把程序的主要代码都移入一个模块,脚本中只剩下导入该模块的引导程序则可以略微缩短脚本的启动时间。 可以有叫做“spam.pyc”(当用了-O标志时为“spam.pyo”)的文件而没有对应的源文件“spam.py”。这可以用来分发一个比较难反编译的Python代码库。
模块compileall可以把一个目录中所有模块编译为“.pyc”文件(指定了-O选项时编译为“.pyo”文件)。Python带有一个标准模块库,在另一个文档《Python库参考》中进行了描述。
一些模块直接编入了解释程序中,这些模块不是语言的核心,为了运行效率或者为了提供对于系统调用这样的系统底层功能而编入了解释程序中。提供那些模块是编译时的选择。
Python中可以用“包”来组织Python模块名字空间,名字引用时可以用“带点的模块名。例如,模块名A.B代表包“A”内名为“B”的子模块。正如使用模块可以使不同模块的作者不用顾虑彼此的全局变量名会冲突,使用带点的模块名可以使多模块包如NumPy和PIL的作者不需要担心彼此的模块名会冲突。
例如,Python模块只在提供amoeba底层指令的系统中才能提供。有一个模块值得特别重视:sys模块,每一个Python解释程序中都编译入了这个模块。变量sys.ps1和sys.ps2定义了交互运行时的初始提示和续行提示。
这两个变量只在解释程序以交互方式运行时才有定义。 变量sys.path是一个字符串列表,由它确定解释程序的模块搜索路径。它被初始化为环境变量PYTHONPATH所指定的缺省路径,环境变量没有定义时初始化为安装时的缺省路径。可以用标准的列表操作修改这个搜索路径,例如:
- >>> import fibo, sys
- >>> dir(fibo)
- ['__name__', 'fib', 'fib2']
- >>> dir(sys)
- ['__name__', 'argv', 'builtin_module_names', 'copyright', 'exit',
- 'maxint', 'modules', 'path', 'ps1', 'ps2', 'setprofile', 'settrace',
- 'stderr', 'stdin', 'stdout', 'version']