Python是一种解释性语言。但是为什么我的源目录包含。pyc文件,这些文件被Windows识别为“编译过的Python文件”?


当前回答

为了加速加载模块,Python将模块的编译内容缓存在.pyc中。

CPython将源代码编译为“字节码”,出于性能考虑,当源文件发生更改时,CPython会将此字节码缓存到文件系统中。这使得Python模块的加载速度更快,因为可以绕过编译阶段。当你的源文件是foo.py时,CPython将字节代码缓存在foo.py文件中。Pyc文件就在源代码旁边。

在python3中,Python的导入机制被扩展为在每个Python包目录中的单个目录中写入和搜索字节码缓存文件。这个目录将被称为__pycache__。

下面是一个描述如何加载模块的流程图:

欲了解更多信息:

裁判:PEP3147 参考:“编译”的Python文件

其他回答

它们包含字节代码,Python解释器将源代码编译为字节代码。这段代码随后由Python的虚拟机执行。

Python的文档是这样解释定义的:

Python是一种解释性语言,例如 而不是编译的 区别可能是模糊的,因为 字节码编译器的存在。 这意味着源文件可以 直接运行而不显式地运行 创建一个可执行文件,然后 运行。

Machines don't understand English or any other languages, they understand only byte code, which they have to be compiled (e.g., C/C++, Java) or interpreted (e.g., Ruby, Python), the .pyc is a cached version of the byte code. https://www.geeksforgeeks.org/difference-between-compiled-and-interpreted-language/ Here is a quick read on what is the difference between compiled language vs interpreted language, TLDR is interpreted language does not require you to compile all the code before run time and thus most of the time they are not strict on typing etc.

它们是由Python解释器在导入.py文件时创建的,它们包含导入模块/程序的“已编译字节码”,其思想是,如果.pyc比相应的.py文件更新,则可以在后续导入时跳过从源代码到字节码的“翻译”(只需完成一次),从而略微加快启动速度。但它仍然是被解释的。

这是为初学者准备的,

在运行脚本之前,Python会自动将脚本编译为已编译的代码,即所谓的字节代码。

运行脚本不被认为是导入,也不会创建.pyc。

例如,如果你有一个脚本文件abc.py,它导入了另一个模块xyz.py,当你运行abc.py时,xyz.py, xyz.py。Pyc将被创建,因为xyz被导入,但没有abc。Pyc文件将被创建,因为abc.py没有被导入。

如果你需要为一个未导入的模块创建一个.pyc文件,你可以使用py_compile和compileall模块。

py_compile模块可以手动编译任何模块。一种方法是交互式地使用该模块中的py_compile.compile函数:

>>> import py_compile
>>> py_compile.compile('abc.py')

这将把.pyc写到与abc.py相同的位置(你可以用可选参数cfile重写它)。

您还可以使用compileall模块自动编译一个或多个目录中的所有文件。

python -m compileall

如果省略目录名(本例中的当前目录),模块将编译sys.path上的所有内容

Python(至少是它最常见的实现)遵循将原始源代码编译为字节码的模式,然后在虚拟机上解释字节码。这意味着(同样,最常见的实现)既不是纯解释器也不是纯编译器。

然而,另一方面,编译过程基本上是隐藏的——.pyc文件基本上被视为缓存;它们能加快速度,但你通常根本不需要注意到它们。它在必要时根据文件时间/日期戳自动使它们失效并重新加载(重新编译源代码)。

我所见过的唯一一次问题是,编译后的字节码文件以某种方式获得了未来的时间戳,这意味着它看起来总是比源文件更新。因为它看起来更新,源文件从来没有重新编译过,所以无论你做了什么更改,它们都被忽略了…