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


当前回答

这是为初学者准备的,

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

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

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

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

Python的*.py文件只是一个文本文件,您可以在其中编写一些代码行。当你试图使用"python filename。py"来执行这个文件时

该命令调用Python虚拟机。Python虚拟机有两个组件:“编译器”和“解释器”。解释器不能直接读取*.py文件中的文本,因此该文本首先被转换为面向PVM(不是硬件,而是PVM)的字节码。PVM执行这个字节代码。*。Pyc文件也会生成,作为运行它的一部分,它会对shell或其他文件中的文件执行导入操作。

如果这个*。Pyc文件已经生成,那么每次你运行/执行你的*.py文件时,系统直接加载你的*.py文件。pyc文件,不需要任何编译(这将节省一些处理器的机器周期)。

一旦*。生成Pyc文件,不需要*.py文件,除非你编辑它。

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

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

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

这是为初学者准备的,

在运行脚本之前,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上的所有内容