如果解释Python,那么.pyc文件是什么?

如果解释Python,那么.pyc文件是什么?,python,compiled,interpreted-language,pyc,Python,Compiled,Interpreted Language,Pyc,我已经了解到Python是一种解释语言… 然而,当我查看我的Python源代码时,我看到了.pyc文件,Windows将其标识为“编译的Python文件” 它们从何而来?它们包含Python解释器编译源代码的目的。这段代码然后由Python的虚拟机执行 Python文档对定义的解释如下: Python是一种解释语言,正如 尽管 由于不同的原因,区别可能会变得模糊 字节码编译器的存在。 这意味着可以删除源文件 直接运行而不显式运行 创建一个可执行文件,然后 跑 它们是在导入.py文件时由Pytho

我已经了解到Python是一种解释语言…
然而,当我查看我的Python源代码时,我看到了
.pyc
文件,Windows将其标识为“编译的Python文件”

它们从何而来?

它们包含Python解释器编译源代码的目的。这段代码然后由Python的虚拟机执行

Python文档对定义的解释如下:

Python是一种解释语言,正如 尽管 由于不同的原因,区别可能会变得模糊 字节码编译器的存在。 这意味着可以删除源文件 直接运行而不显式运行 创建一个可执行文件,然后 跑


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

我已经明白了这一点 Python是一种解释语言

这种流行的模因是不正确的,或者更确切地说,是建立在对(自然)语言水平的误解之上的:类似的错误是说“圣经是一本精装书”。让我解释一下这个比喻

“圣经”是“一本书”,在某种意义上说,它是一类(实际的、物理的物体被识别为)书;被认定为“圣经副本”的书籍应该有一些基本的共同点(内容,尽管可能是不同的语言,有不同的可接受的翻译、脚注和其他注释)——但是,这些书完全可以在许多方面有所不同,而这些方面并不被认为是基本的——装订的种类、装订的颜色、印刷时使用的字体、插图(如果有的话)、宽大的可写边距、数字和内置书签的种类等等

很有可能一本典型的《圣经》印刷品确实是精装的——毕竟,这本书通常要反复阅读,在几个地方加上书签,翻阅给定的章节和诗句指针,等等,一个好的精装本在这种情况下可以使一本书更耐用。然而,这些都是世俗的(实际的)问题,不能用来确定一个给定的实际书籍对象是否是圣经的副本:平装印刷是完全可能的

类似地,从定义一类语言实现的意义上来说,Python是一种“语言”,这些实现必须在一些基本方面(语法、大多数语义,除了那些明确允许它们不同的部分)相似,但在几乎每个“实现”中完全允许不同详细信息——包括他们如何处理给定的源文件,是否将源文件编译成一些较低级别的表单(如果是,是哪种表单——以及是否将这些编译后的表单保存到磁盘或其他地方),如何执行所述表单,等等

经典的实现CPython通常简称为“Python”——但它只是几个生产质量实现之一,与微软的IronPython(编译成CLR代码,即“.NET”)、Jython(编译成JVM代码)、PyPy并列(它是用Python编写的,可以编译成各种各样的“后端”形式,包括“即时”生成的机器语言)。它们都是Python(=“Python语言的实现”),就像许多表面上不同的书籍对象都可以是圣经(=“圣经的副本”)

如果您对CPython特别感兴趣:它将源文件编译成特定于Python的低级形式(称为“字节码”),在需要时自动执行(当源文件没有对应的字节码文件时,或者字节码文件比源文件旧,或者由不同的Python版本编译时),通常将字节码文件保存到磁盘(以避免将来重新编译)。OTOH IronPython通常将编译为CLR代码(是否保存到磁盘,具体取决于)和Jython编译为JVM代码(是否保存到磁盘--如果保存它们,将使用
.class
扩展名)

然后,这些较低级别的表单由适当的“虚拟机”(也称为“解释器”)执行——CPython VM、.Net运行时、.Java VM(又名JVM),视情况而定

因此,从这个意义上讲(典型的实现会做什么),Python是一种“解释语言”,当且仅当C#和Java是:它们都有一种典型的实现策略,即首先生成字节码,然后通过VM/解释器执行

更可能的焦点是“重”的程度CPython被设计成以尽可能快的速度、尽可能轻的量、尽可能少的礼节进行编译——编译器很少进行错误检查和优化,因此它可以在少量内存中快速运行,从而使它能够自动透明地运行在需要的时候,用户甚至不需要知道编译正在进行,大多数时候。Java和C#通常在编译过程中接受更多的工作(因此不执行自动编译)为了更彻底地检查错误并执行更多优化,这是一个连续的灰度图,而不是黑或白的情况,在某个给定级别设置一个阈值并说只有在该级别之上才称之为“编译”!-)

Python(至少是最常见的实现
>>> import py_compile
>>> py_compile.compile('abc.py')
python -m compileall