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

我已经了解到Python是一种解释型语言......但是,当我查看我的Python源代码时,我看到了Windows标识为“编译的Python文件”的.pyc文件。 这些进来了?


它们包含字节代码,这是Python解释器编译源代码的地方。 这段代码然后由Python的虚拟机执行。

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

Python是一种解释型语言,与编译型语言相反,但由于字节码编译器的存在,区别可能会很模糊。 这意味着源文件可以直接运行,而无需显式创建一个可执行文件,然后运行该文件。


我已经了解到Python是一种解释型语言......

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

“圣经”是作为一 (实际的,物理的物体被确定为)书籍的意义上的“一本书”; 被认为是“圣经副本”的书籍应该有一些共同的基本内容(即使这些内容可以是不同的语言,不同的可接受的翻译,脚注的水平和其他注释) - 然而,这些书是完全可以允许在许多不被认为是基本的方面有所不同 - 有约束力,装订颜色,打印中使用的字体,插图(如果有的话),宽可写边距与否,内置书签的数量与种类, 等等等等。

很可能典型的圣经印刷确实是精装书 - 毕竟,它是一本通常要反复阅读,在几处书签的书,通过寻找给定的章节和诗节指针等,等等,并且一个好的精装书可以使得给定的副本在这种使用下更长时间。 然而,这些都是世俗(实用)的问题,无法用来确定给定的实际书本对象是否是圣经的副本:平装打印完全可能!

同样,从定义一类语言实现的角度来看,Python是“一种语言”,它必须在某些基本方面(语法,大多数语义,除了明确允许区分的那些部分外)都是相似的,但是完全允许几乎每个“实现”细节都有所不同 - 包括它们如何处理源文件,它们是否将源代码编译为一些较低级别的表单(如果是,则是哪种形式)以及它们是否保存了这些编译后的表格,磁盘或其他地方),他们如何执行所述表单等等。

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

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

这些较低级别的表单然后由合适的“虚拟机”(也称为“解释器”)执行 - CPython VM,.Net运行时,Java VM(又名JVM)。

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

更可能关注的是编译过程如何“沉重”,缓慢和高度。 CPython被设计为尽可能快地编译,尽可能轻量级,尽可能少的仪式 - 编译器很少进行错误检查和优化,因此它可以快速运行并存储少量内存,从而可以让它在需要时自动且透明地运行,而用户甚至不需要意识到大部分时间都在进行编辑。 Java和C#在编译过程中通常会接受更多的工作(因此不会执行自动编译),以便更彻底地检查错误并执行更多优化。 它是一个灰度级的连续体,而不是黑色或白色的情况,在某个给定的水平上设置一个阈值并且说只有在这个水平之上时,你才称它为“编译”! - )


没有解释型语言这样的东西。 无论是使用解释器还是编译器,纯粹是实现的一个特点,并且与该语言完全没有任何关系。

每种语言都可以通过解释器或编译器来实现。 绝大多数语言每种类型至少有一个实现。 (例如,有C和C ++的解释器,还有用于JavaScript,PHP,Perl,Python和Ruby的编译器。)此外,大多数现代语言实现实际上结合了解释器和编译器(或甚至多个编译器)。

语言只是一组抽象的数学规则。 解释器是一种语言的几种具体实施策略之一。 这两个生活在完全不同的抽象层次上。 如果英文是一种类型语言,那么术语“解释语言”将是一种类型错误。 “Python是一种解释型语言”这句话不仅仅是错误的(因为假如语句甚至是有意义的,即使它是错误的),它也只是没有意义,因为语言永远不能被定义为“解释。”

特别是,如果您查看当前现有的Python实现,这些是他们正在使用的实现策略:

  • IronPython:编译为DLR然后编译为CIL字节码的DLR树。 CIL字节码会发生什么变化取决于您运行的CLI VES,但Microsoft .NET,GNU Portable.NET和Novell Mono最终会将其编译为本机机器码。
  • Jython:解释Python源代码直到它识别出热代码路径,然后编译为JVML字节码。 JVML字节码会发生什么取决于您正在运行哪个JVM。 Maxine将直接将其编译为未优化的本地代码,直到它识别出热代码路径,然后重新编译为优化的本地代码。 HotSpot将首先解释JVML字节码,然后编译热码路径以优化机器码。
  • PyPy:编译成PyPy字节码,PyPy字节码然后被PyPy VM解释,直到它识别出它随后编译成本地代码,JVML字节码或CIL字节码的热码路径,这取决于你在哪个平台上运行。
  • CPython:编译为CPython字节码,然后解释它。
  • 无堆栈Python:编译为CPython字节码,然后解释它。
  • Unladen Swallow:编译为CPython字节码,然后解释它,直到它识别编译为LLVM IR的热代码路径,然后LLVM编译器将其编译为本机机器码。
  • 您可能会注意到,该列表中的每个实现(以及其他一些我没有提到的实现,例如tinypy,Shedskin或Psyco)都有一个编译器。 实际上,据我所知,目前还没有纯粹解释的Python实现,没有这样的实现计划,也没有这样的实现。

    “解释型语言”这个术语不仅没有意义,即使你把它解释为“解释性实施的语言”,这显然是不正确的。 谁告诉你的,显然不知道他在说什么。

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

    链接地址: http://www.djcxy.com/p/67885.html

    上一篇: If Python is interpreted, what are .pyc files?

    下一篇: How do I fix PyDev "Undefined variable from import" errors?