在前面教程中介绍的自定义模块中,如果我们使用了关键字“import”导入自定义的模块并运行之后,我们点击进入该模块文件的目录,会发现在模块的同一目录下会生成一个名为“_pycache_”的目录,里面有个和模块文件名相同,但是后缀为“.pyc”的神秘文件。在本节教程中,我们将介绍pyc文件的基础知识。
1、什么是pyc文件
pyc就是python compiled(python编译)的缩写,pyc文件是官方开发的,经过解释器编译过生成的文件,它是二进制文件,是一种byte code字节码。“.py”文件变成“.pyc”文件后,加载的速度有所提高,而且pyc是一种跨平台的字节码,是由Python的虚拟机来执行的,这个类似于Java或者.NET的虚拟机的概念,从而实现跨平台。pyc文件经过python解释器最终会生成机器码运行。所以pyc文件是可以跨平台部署的,因此Python具有良好的可移植性。
每个pyc文件会被自动保存在一个名为“_pycache_”文件夹下。而且pyc文件命名是有规律的,比如某个test.py文件经过编译会生成test.cpython-38.pyc文件,这里的cpython-38,表示c编写的Python解释器,Python解释器版本是38。pyc文件的作用是加速程序的执行,使用关键字“import”导入模块时,解释器会先编译该模块,生成pyc文件。如果对模块中“.py”的源文件进行了修改,所对应的pyc文件也会自动更新。模块中有了“.pyc”文件后,下次程序运行时,如果没有修改过源码,Python将会直接加载pyc文件并跳过编译这个步骤,从而加快程序启动速度。
这里需要注意的是,pyc的内容是跟Python的版本相关的,不同版本编译后的pyc文件是不同的,比如Python3.9版本编译的pyc文件,是无法在Python3.8版本中执行的。
2、为什么需要pyc文件
众所周知,Python是一种解释型高级编程语言,运行的时候需要通过Python解释器解释执行。我们知道解释型语言最大的问题是运行速度比编译性语言慢,因为编译性语言会产生二进制执行文件,运行速度会更快。所以如果先编译出pyc文件后,可以避免每次执行程序时都要重新解释一遍源代码,从而提高程序的运行速度。
pyc文件的另外一个优点是可以直接在Python解释器中运行。比如要运行“Pyhint\Learn-Python\test”文件夹内的test.pyc文件,可以进入Pyhint编辑器,打开终端窗口,输入“python test.pyc”按下Enter回车键即可运行二进制文件“test.pyc”内的代码,所以很多商业软件为了隐藏源码,会把所有的“.py”文件编译为pyc后,再发布出去。虽然这种方式可以在一定程度上起到代码保密的作用,但是这种保密比较弱,懂行的人可以轻轻松松做反编译。
在实际的项目开发中,我们会发现有的py文件产生pyc,而有的py文件不产生pyc。pyc文件只有在文件被当成模块导入时才会生成。也就是说,Python解释器认为,只有import进行的模块才需要被重用。 生成pyc文件的好处显而易见,当我们多次运行程序时,不需要重新对该模块进行重新解释。当有别的程序再次使用关键字“import”导入这些模块时,Python就不用再重新解析py文件,而是读入pyc文件就可以了。
3、如何手动生成pyc文件
任何py文件都可以编译为pyc文件,Python提供了内置的类库来实现手动把py文件编译为pyc文件,这个模块就是py_compile模块。例如:
动手练一练:
import py_compile
py_compile.compile("test.py")
我们打开Pyhint编辑器,在“Pyhint\condition”文件夹内新建一个test.py文件,在Pyhint编辑器代码框内输入以上代码,点击运行后会自动在“Pyhint\condition”的同一目录下生成一个“_pycache_”目录,里面会出现一个“test.cpython-38.pyc”文件。
还可以通过cmd终端窗口生成pyc文件,比如在“Pyhint\Learn-Python\test”文件夹内新建一个test.py文件,进入Pyhint编辑器,打开cmd终端窗口,输入“python -m py_compile test.py”按下Enter回车键即可自动在“Pyhint\Learn-Python\test”的同一目录下生成一个“_pycache_”目录,里面会出现一个“test.cpython-38.pyc”文件。
我们同样可以批量生成pyc文件。通常情况下,我们的项目都是在一个目录下的,一般不会说仅仅编译一个py文件而已,而是需要把整个文件夹下的py文件都编译为pyc文件,Python又为了我们提供了另一个模块:compileall模块 。例如:
动手练一练:
import compileall
compileall.compile_dir('D:\\test')
执行以上代码,输出结果为:
Listing 'D:\\test'...
Compiling 'D:\\test\\funs.py'...
Compiling 'D:\\test\\test.py'...
上面的例子中,我们在“D盘”文件夹内新建一个test文件夹,test文件夹内创建“funs.py”和“test.py”两个py文件,打开Pyhint编辑器,然后在Pyhint编辑器代码框内输入以上代码,点击运行后会自动在“D:\test”的同一目录下生成一个“_pycache_”目录,里面会出现两个“.pyc”文件。