首先考虑.pyc文件类型,当你导入一个模块时,解释器会自动生成.pyc文件,这样会节省下次导入的时间。当有模块被导入的时候,解释器也会产生.pyo文件,只不过需要告诉解释器开启优化设置。
一、python .pyc .pyd .pyo文件的区别
.pyc文件类型
我们首先考虑.pyc文件类型,当你导入一个模块时,解释器会自动生成.pyc文件,这样会节省下次导入的时间。
举个例子,下面是一个python模块,用来计算阶乘,我们想在其他模块中导入该模块。
# math_helpers.py
# a function that computes the nth factorial, e.g. factorial(2)
def factorial(n):
if n == 0:
return 1
else:
return n * factorial(n – 1)
# a main function that uses our factorial function defined above
def main():
print(“I am the factorial helper”)
print(“you can call factorial(number) where number is any integer”)
print(“for example, calling factorial(5) gives the result:”)
print(factorial(5))
# this runs when the script is called from the command line
if __name__ == ‘__main__’:
main()
当我们使用命令python math_helpers.py来运行这个模块的时候,不会产生.pyc文件。
现在我们可以把该模块导入其他模块,比如像下面这样。我们从math_helpers.py导入factorial函数,并且使用该函数计算6的阶乘。
# computations.py
# import from the math_helpers module
from math_helpers import factorial
# a function that makes use of the imported function
def main():
print(“Python can compute things easily from the REPL”)
print(“for example, just write : 4 * 5”)
print(“and you get: 20.”)
print(“Computing things is easier when you use helpers”)
print(“Here we use the factorial helper to find the factorial of 6”)
print(factorial(6))
# this runs when the script is called from the command line
if __name__ == ‘__main__’:
main()
然后我们在终端输入python computations.py来运行脚本,我们不仅会得到6的阶乘是720,还会注意到解释器自动生成了math_helpers.cpython-39.pyc文件。会产生.pyc文件的主要原因是在computations模块中导入了math_helpers模块。为了在将来使用时可以加快导入的速度,解释器创建了该模块的字节码文件。
当源代码文件被更新的时候,.pyc文件也会被更新。即只要源代码文件的更新时间和字节码文件的更新时间不一样,字节码文件就会更新以保持一致。
注意,使用.pyc文件只是加速程序加载的时间,而不是加速程序执行的时间。也就是说,你可以把主程序写在一个模块,然后被其他的较小的模块调用,以此来加速程序的启动时间。但是,如果想获得程序性能的改进,你需要从算法上或者其他方面进行优化。
因为.pyc文件是平台不相关的,所以可以在不同架构的机器上使用同一个.pyc文件。然而,如果开发者在他们的系统上使用不同的时钟时间,在生成.pyc文件的时候同时生成时间戳,将来其他的开发者读取这个时间戳,这可能导致对源码进行修改的时候不会修改字节码,这是一个不容易被发现的严重的bug。较好的方式就是把在进行版本控制的时候忽略pyc文件。
.pyo文件类型
当有模块被导入的时候,解释器也会产生.pyo文件,只不过需要告诉解释器开启优化设置。
当我们调用解释器的时候,只需要加上-O就可以开启优化设置。下面是一个例子,首先,我们有一个模块定义了一个lambda函数。
# lambdas.py
# a lambda that returns double whatever number we pass it
g = lambda x: x * 2
如果你记得前一个例子,我们需要导入这个模块以使用它里面的函数,我们导入lambdas.py并使用里面的g函数。
# using_lambdas.py
# import the lambdas module
import lambdas
# a main function in which we compute the double of 7
def main():
print(lambdas.g(7))
# this executes when the module is invoked as a script at the command line
if __name__ == ‘__main__’:
main()
现在,我们不是像上个例子那样调用python解释器,而是添加优化选项。这样可以产生更小的字节码文件。命令如下:
python -O using_lambdas.py
如果我们使用python3.5以前的版本运行上面的命令,就会产生pyo文件。从python3.5开始,将不再产生pyo文件,而是lambdas.cpython-39.opt-1.pyc文件。
优化器一般情况下不会做特别多的工作,只是从你的字节码中移除assert语句。在大多数情况下感受不出来区别,但是执行次数多的话可能会有影响。
产生.pyo文件就不再产生.pyc文件了(python3.5以前是.pyo,python3.5以后就是产生.opt-1.pyc文件)。源代码变化的时候,.pyo或.opt-1.pyc也会随着变化。
.pyd文件类型
和前两个相比,.pyd文件类型是平台相关的,只和Windows平台有关系。
在Windows平台下,.pyd文件是一个包含python代码的库,可以被其他的python程序调用,为了让这个库可以被其他python程序调用,被打包成动态链接库(dynamic link library)。
动态链接库是Windows平台下的代码库,在运行时被调用。它有利于代码重用、代码模块化,并且可以更快的启动程序。因此,DLL在Windows操作系统中发挥了重要作用。
总结
.pyc和.pyo都包含字节码文件,但是.pyo更紧凑。
.pyd是动态链接库,只会在Windows操作系统中见到。
所有这些类型的文件都是被其他的python程序调用。
延伸阅读:
二、什么是Python
Python是一种跨平台的计算机程序设计语言。 是一个高层次的结合了解释性、编译性、互动性和面向对象的脚本语言。最初被设计用于编写自动化脚本(shell),随着版本的不断更新和语言新功能的添加,越多被用于独立的、大型项目的开发。