如之前提到的,Python储存字节代码文件的方式在Python3.2之后有所改变。首先,如果因为某些原因Python无法在你的电脑上读写文件,你的程序仍然会正常运行——Python在创建字节代码文件之后会把它存在内存中并使用,在退出之后便废弃。为了加快启动的速度,Python会尝试把字节代码文件存在文件中以便下一次使用跳过编译步骤。但做的方式却不尽相同:
Python3.X之前的版本(包括所有Python2.x)
字节代码文件储存在文件中并和相应的源文件在同一目录,通常文件后缀是.pyc
。字节代码文件在内部也有一个带有Python版本标记的戳,以便Python知道当你机器上运行的Python版本不同时重新编译。例如,如果你更新了你的Python版本,并且两种版本的字节代码文件不同,所有的字节代码文件都会因为Python版本号不匹配而重新编译,即使你并没有改变源代码。
Python3.2之后的版本
字节代码文件储存在一个名叫__pycache__的子目录中,这个目录在必要的时候会创建并和源文件在相同的目录。这也避免了代码目录的混乱。尽管字节代码文件的后缀名仍然是.pyc
,但在名字中包含了创建该文件的Python版本信息(例如 module.cpython-32.pyc),这也避免了冲突和重编译:因为在__pycache__子目录中每个版本的Python都有包含自己独特版本号命名的字节代码文件,在特定Python版本下运行并不会覆盖其他版本的字节代码文件,从而不需要重编译。严格的讲,名字中也包含创建它们的Python名字,从而CPython、JPython等可以共存在同一台机器上而不会影响彼此的运行。
例子
Python3.2之前的版本
c:\code\py2x> dir
10/31/2012 10:58 AM 39 script0.py
c:\code\py2x> C:\python27\python
>>> import script0
hello world
1267650600228229401496703205376
>>> ^Z
c:\code\py2x> dir
10/31/2012 10:58 AM 39 script0.py
10/31/2012 11:00 AM 154 script0.pyc
在Python3.2之后的版本
c:\code\py2x> cd ..\py3x
c:\code\py3x> dir
10/31/2012 10:58 AM 39 script0.py
c:\code\py3x> C:\python33\python
>>> import script0
hello world
1267650600228229401496703205376
>>> ^Z
c:\code\py3x> dir
10/31/2012 10:58 AM 39 script0.py
10/31/2012 11:00 AM <DIR> __pycache__
c:\code\py3x> dir __pycache__
10/31/2012 11:00 AM 184 script0.cpython-33.pyc
在3.2之后的版本,不同的Python引用相同的文件会产生不同的字节代码文件:
c:\code\py3x> C:\python32\python
>>> import script0
hello world
1267650600228229401496703205376
>>> ^Z
c:\code\py3x> dir __pycache__
10/31/2012 12:28 PM 178 script0.cpython-32.pyc
10/31/2012 11:00 AM 184 script0.cpython-33.pyc