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

2024-04-26 05:11:38 发布

您现在位置:Python中文网/ 问答频道 /正文

我已经明白了Python是一种解释性语言。。。然而,当我查看Python源代码时,我看到了.pyc文件,Windows将其标识为“编译的Python文件”。这些是哪里来的?


Tags: 文件语言源代码windows标识pyc解释性
3条回答

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

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

Python is an interpreted language, as opposed to a compiled one, though the distinction can be blurry because of the presence of the bytecode compiler. This means that source files can be run directly without explicitly creating an executable which is then run.

I've been given to understand that Python is an interpreted language...

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

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

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

类似地,Python在定义一类语言实现的意义上是“一种语言”,在某些基本方面(语法,除了那些明确允许它们不同的部分之外,大多数语义在几乎每个“实现”细节上都是完全允许不同的——包括它们如何处理给定的源文件,它们是否将源代码编译成一些较低级别的表单(如果是的话,是哪种表单——以及它们是否保存这样编译的表单,磁盘或其他地方),它们如何执行所述表单,等等。

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

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

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

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

更可能的是,重点是如何“沉重”,缓慢,高仪式的编纂过程。CPython被设计成尽可能快的编译,尽可能轻的编译,尽可能少的仪式——编译器确实ry很少进行错误检查和优化,因此它可以在少量内存中快速运行,这反过来又允许它在需要时自动透明地运行,而用户甚至不需要知道大部分时间都在进行编译。Java和C通常在编译期间接受更多的工作(因此不执行自动编译),以便更彻底地检查错误并执行更多优化。这是一个连续的灰色等级,不是黑色或白色的情况,这将是完全武断的,把一个门槛在某个给定的水平,并说,只有高于这个水平,你称之为“编译”!-)

不存在解释性语言。无论使用的是解释器还是编译器,都是实现的一个特性,与语言完全无关。

每种语言都可以由解释器或编译器实现。绝大多数语言至少有每种类型的一个实现。(例如,C和C++有解释器,JavaScript、PHP、Perl、Python和Ruby都有编译器)。此外,大多数现代语言实现实际上同时包括解释器和编译器(甚至多个编译器)。

语言只是一套抽象的数学规则。解释器是语言的几种具体实现策略之一。这两者生活在完全不同的抽象层次上。如果英语是一种类型语言,“解释语言”一词将是一种类型错误。语句“Python是一种解释性语言”不仅是false(因为false意味着语句甚至是有意义的,即使它是错误的),它只是普通意义上的,而不是有意义的,因为一种语言可以从不被定义为“解释性的”

特别是,如果您查看当前现有的Python实现,它们使用的实现策略如下:

  • IronPython:编译成DLR树,然后DLR编译成CIL字节码。CIL字节码的情况取决于您运行的是哪个clive,但是Microsoft.NET、GNU Portable.NET和Novell Mono最终会将其编译为本机代码。
  • Jython:解释Python源代码,直到它标识出热代码路径,然后编译成JVML字节码。JVML字节码的变化取决于您运行的JVM。Maxine将直接将其编译为未优化的本机代码,直到它标识出热代码路径,然后重新编译为优化的本机代码。HotSpot将首先解释JVML字节码,然后最终将热代码路径编译为优化的机器代码。
  • PyPy:编译成pypypy字节码,然后由PyPy VM解释,直到它标识热代码路径,然后根据运行的平台编译成本机代码、JVML字节码或CIL字节码。
  • CPython:编译成CPython字节码,然后对其进行解释。
  • 无堆栈Python:编译成CPython字节码,然后解释。
  • Unladen Swallow:编译成CPython字节码,然后对其进行解释,直到识别出热代码路径,然后编译成LLVM-IR,LLVM编译器再编译成本机代码。
  • Cython:将Python代码编译成可移植的C代码,然后用标准的C编译器编译
  • NUITKA:将Python代码编译成机器相关的C++代码,然后用标准的C编译器
  • 编译

你可能会注意到列表中的每个实现(加上一些我没有提到的其他实现,比如tinypy、Shedskin或Psyco)都有一个编译器。事实上,据我所知,目前还没有纯解释的Python实现,也没有计划过这样的实现,也从来没有这样的实现。

“解释性语言”一词不仅没有意义,即使你把它解释为“有解释性实现的语言”,它显然也不是真的。不管是谁告诉你的,显然都不知道他在说什么。

特别是,您看到的.pyc文件是由CPython、Stackless Python或Unladen Swallow生成的缓存字节码文件。

相关问题 更多 >

    热门问题