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

发布于 2024-09-04 07:33:51 字数 90 浏览 6 评论 0原文

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

Python is an interpreted language. But why does my source directory contain .pyc files, which are identified by Windows as "Compiled Python Files"?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(12

裂开嘴轻声笑有多痛 2024-09-11 07:33:51

我已经明白了这一点
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)(视情况而定)。

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

更有可能的是,焦点在于编译过程有多么“沉重”、缓慢和仪式感。 CPython 被设计为尽可能快地编译、尽可能轻量级、尽可能少的仪式——编译器很少进行错误检查和优化,因此它可以快速运行并占用少量内存,这反过来又让它在需要时自动、透明地运行,大多数时候用户甚至不需要知道正在进行编译。 Java 和 C# 通常在编译期间接受更多工作(因此不执行自动编译),以便更彻底地检查错误并执行更多优化。它是灰度的连续体,而不是黑色或白色的情况,并且在某个给定级别设置阈值并说只有高于该级别才将其称为“编译”是完全任意的!-)

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

This popular meme is incorrect, or, rather, constructed upon a misunderstanding of (natural) language levels: a similar mistake would be to say "the Bible is a hardcover book". Let me explain that simile...

"The Bible" is "a book" in the sense of being a class of (actual, physical objects identified as) books; the books identified as "copies of the Bible" are supposed to have something fundamental in common (the contents, although even those can be in different languages, with different acceptable translations, levels of footnotes and other annotations) -- however, those books are perfectly well allowed to differ in a myriad of aspects that are not considered fundamental -- kind of binding, color of binding, font(s) used in the printing, illustrations if any, wide writable margins or not, numbers and kinds of builtin bookmarks, and so on, and so forth.

It's quite possible that a typical printing of the Bible would indeed be in hardcover binding -- after all, it's a book that's typically meant to be read over and over, bookmarked at several places, thumbed through looking for given chapter-and-verse pointers, etc, etc, and a good hardcover binding can make a given copy last longer under such use. However, these are mundane (practical) issues that cannot be used to determine whether a given actual book object is a copy of the Bible or not: paperback printings are perfectly possible!

Similarly, Python is "a language" in the sense of defining a class of language implementations which must all be similar in some fundamental respects (syntax, most semantics except those parts of those where they're explicitly allowed to differ) but are fully allowed to differ in just about every "implementation" detail -- including how they deal with the source files they're given, whether they compile the sources to some lower level forms (and, if so, which form -- and whether they save such compiled forms, to disk or elsewhere), how they execute said forms, and so forth.

The classical implementation, CPython, is often called just "Python" for short -- but it's just one of several production-quality implementations, side by side with Microsoft's IronPython (which compiles to CLR codes, i.e., ".NET"), Jython (which compiles to JVM codes), PyPy (which is written in Python itself and can compile to a huge variety of "back-end" forms including "just-in-time" generated machine language). They're all Python (=="implementations of the Python language") just like many superficially different book objects can all be Bibles (=="copies of The Bible").

If you're interested in CPython specifically: it compiles the source files into a Python-specific lower-level form (known as "bytecode"), does so automatically when needed (when there is no bytecode file corresponding to a source file, or the bytecode file is older than the source or compiled by a different Python version), usually saves the bytecode files to disk (to avoid recompiling them in the future). OTOH IronPython will typically compile to CLR codes (saving them to disk or not, depending) and Jython to JVM codes (saving them to disk or not -- it will use the .class extension if it does save them).

These lower level forms are then executed by appropriate "virtual machines" also known as "interpreters" -- the CPython VM, the .Net runtime, the Java VM (aka JVM), as appropriate.

So, in this sense (what do typical implementations do), Python is an "interpreted language" if and only if C# and Java are: all of them have a typical implementation strategy of producing bytecode first, then executing it via a VM/interpreter.

More likely the focus is on how "heavy", slow, and high-ceremony the compilation process is. CPython is designed to compile as fast as possible, as lightweight as possible, with as little ceremony as feasible -- the compiler does very little error checking and optimization, so it can run fast and in small amounts of memory, which in turns lets it be run automatically and transparently whenever needed, without the user even needing to be aware that there is a compilation going on, most of the time. Java and C# typically accept more work during compilation (and therefore don't perform automatic compilation) in order to check errors more thoroughly and perform more optimizations. It's a continuum of gray scales, not a black or white situation, and it would be utterly arbitrary to put a threshold at some given level and say that only above that level you call it "compilation"!-)

香橙ぽ 2024-09-11 07:33:51

它们包含字节代码,这是Python解释器将源代码编译成的内容。然后,该代码由 Python 的虚拟机执行。

Python 文档 解释了如下定义:

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

They contain byte code, which is what the Python interpreter compiles the source to. This code is then executed by Python's virtual machine.

Python's documentation explains the definition like this:

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.

野生奥特曼 2024-09-11 07:33:51

不存在解释性语言这样的东西。使用解释器还是编译器纯粹是实现的一个特征,与语言完全无关。

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

语言只是一组抽象的数学规则。解释器是一种语言的几种具体实现策略之一。这两者生活在完全不同的抽象层次上。如果英语是一种类型语言,那么术语“解释语言”将是类型错误。 “Python 是一种解释性语言”这一说法不仅是错误的(因为错误意味着该说法甚至是有道理的,即使它是错误的),它只是简单地没有意义,因为一种语言永远不能被定义为“解释型”。

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

  • IronPython:编译为 DLR 树,然后 DLR 将其编译为 CIL 字节码。 CIL 字节码会发生什么情况取决于您运行的 CLI VES,但 Microsoft .NET、GNU Portable.NET 和 Novell Mono 最终会将其编译为本机机器代码。
  • Jython:解释 Python 源代码,直到识别出热代码路径,然后将其编译为 JVML 字节码。 JVML 字节码会发生什么取决于您运行的 JVM。 Maxine 将直接将其编译为未优化的本机代码,直到识别出热代码路径,然后将其重新编译为优化的本机代码。 HotSpot将首先解释JVML字节码,然后最终将热代码路径编译为优化的机器代码。
  • PyPy:编译为 PyPy 字节码,然后由 PyPy VM 解释,直到识别出热代码路径,然后将其编译为本机代码、JVML 字节码或 CIL 字节码,具体取决于您运行的平台。
  • CPython:编译为 CPython 字节码,然后进行解释。
  • Stackless 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 生成的缓存字节码文件。

There is no such thing as an interpreted language. Whether an interpreter or a compiler is used is purely a trait of the implementation and has absolutely nothing whatsoever to do with the language.

Every language can be implemented by either an interpreter or a compiler. The vast majority of languages have at least one implementation of each type. (For example, there are interpreters for C and C++ and there are compilers for JavaScript, PHP, Perl, Python and Ruby.) Besides, the majority of modern language implementations actually combine both an interpreter and a compiler (or even multiple compilers).

A language is just a set of abstract mathematical rules. An interpreter is one of several concrete implementation strategies for a language. Those two live on completely different abstraction levels. If English were a typed language, the term "interpreted language" would be a type error. The statement "Python is an interpreted language" is not just false (because being false would imply that the statement even makes sense, even if it is wrong), it just plain doesn't make sense, because a language can never be defined as "interpreted."

In particular, if you look at the currently existing Python implementations, these are the implementation strategies they are using:

  • IronPython: compiles to DLR trees which the DLR then compiles to CIL bytecode. What happens to the CIL bytecode depends upon which CLI VES you are running on, but Microsoft .NET, GNU Portable.NET and Novell Mono will eventually compile it to native machine code.
  • Jython: interprets Python sourcecode until it identifies the hot code paths, which it then compiles to JVML bytecode. What happens to the JVML bytecode depends upon which JVM you are running on. Maxine will directly compile it to un-optimized native code until it identifies the hot code paths, which it then recompiles to optimized native code. HotSpot will first interpret the JVML bytecode and then eventually compile the hot code paths to optimized machine code.
  • PyPy: compiles to PyPy bytecode, which then gets interpreted by the PyPy VM until it identifies the hot code paths which it then compiles into native code, JVML bytecode or CIL bytecode depending on which platform you are running on.
  • CPython: compiles to CPython bytecode which it then interprets.
  • Stackless Python: compiles to CPython bytecode which it then interprets.
  • Unladen Swallow: compiles to CPython bytecode which it then interprets until it identifies the hot code paths which it then compiles to LLVM IR which the LLVM compiler then compiles to native machine code.
  • Cython: compiles Python code to portable C code, which is then compiled with a standard C compiler
  • Nuitka: compiles Python code to machine-dependent C++ code, which is then compiled with a standard C compiler

You might notice that every single one of the implementations in that list (plus some others I didn't mention, like tinypy, Shedskin or Psyco) has a compiler. In fact, as far as I know, there is currently no Python implementation which is purely interpreted, there is no such implementation planned and there never has been such an implementation.

Not only does the term "interpreted language" not make sense, even if you interpret it as meaning "language with interpreted implementation", it is clearly not true. Whoever told you that, obviously doesn't know what he is talking about.

In particular, the .pyc files you are seeing are cached bytecode files produced by CPython, Stackless Python or Unladen Swallow.

将军与妓 2024-09-11 07:33:51

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

These are created by the Python interpreter when a .py file is imported, and they contain the "compiled bytecode" of the imported module/program, the idea being that the "translation" from source code to bytecode (which only needs to be done once) can be skipped on subsequent imports if the .pyc is newer than the corresponding .py file, thus speeding startup a little. But it's still interpreted.

歌枕肩 2024-09-11 07:33:51

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

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

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

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

在此处输入图像描述

有关详细信息:

参考:PEP3147
ref:“编译”Python 文件

To speed up loading modules, Python caches the compiled content of modules in .pyc.

CPython compiles its source code into "byte code", and for performance reasons, it caches this byte code on the file system whenever the source file has changes. This makes loading of Python modules much faster because the compilation phase can be bypassed. When your source file is foo.py , CPython caches the byte code in a foo.pyc file right next to the source.

In python3, Python's import machinery is extended to write and search for byte code cache files in a single directory inside every Python package directory. This directory will be called __pycache__ .

Here is a flow chart describing how modules are loaded:

enter image description here

For more information:

ref:PEP3147
ref:“Compiled” Python files

温暖的光 2024-09-11 07:33:51

这适合初学者,

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

运行脚本不被视为导入,并且不会创建 .pyc。

例如,如果您有一个导入另一个模块 xyz.py 的脚本文件 abc.py,则当您运行 abc.py 时,xyz.pyc,但由于未导入 abc.py,因此不会创建 abc.pyc 文件。

如果需要为未导入的模块创建 .pyc 文件,可以使用 py_compilecompileall 模块。

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

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

这会将 .pyc 写入与 abc.py 相同的位置(您可以使用可选参数 cfile 覆盖它) /代码>)。

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

python -m compileall

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

THIS IS FOR BEGINNERS,

Python automatically compiles your script to compiled code, so called byte code, before running it.

Running a script is not considered an import and no .pyc will be created.

For example, if you have a script file abc.py that imports another module xyz.py, when you run abc.py, xyz.pyc will be created since xyz is imported, but no abc.pyc file will be created since abc.py isn’t being imported.

If you need to create a .pyc file for a module that is not imported, you can use the py_compile and compileall modules.

The py_compile module can manually compile any module. One way is to use the py_compile.compile function in that module interactively:

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

This will write the .pyc to the same location as abc.py (you can override that with the optional parameter cfile).

You can also automatically compile all files in a directory or directories using the compileall module.

python -m compileall

If the directory name (the current directory in this example) is omitted, the module compiles everything found on sys.path

烟织青萝梦 2024-09-11 07:33:51

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

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

我唯一一次看到这个问题是编译后的字节码文件以某种方式获得了未来的时间戳,这意味着它总是看起来比源文件更新。由于它看起来较新,源文件从未重新编译,因此无论您进行什么更改,它们都会被忽略......

Python (at least the most common implementation of it) follows a pattern of compiling the original source to byte codes, then interpreting the byte codes on a virtual machine. This means (again, the most common implementation) is neither a pure interpreter nor a pure compiler.

The other side of this is, however, that the compilation process is mostly hidden -- the .pyc files are basically treated like a cache; they speed things up, but you normally don't have to be aware of them at all. It automatically invalidates and re-loads them (re-compiles the source code) when necessary based on file time/date stamps.

About the only time I've seen a problem with this was when a compiled bytecode file somehow got a timestamp well into the future, which meant it always looked newer than the source file. Since it looked newer, the source file was never recompiled, so no matter what changes you made, they were ignored...

唯憾梦倾城 2024-09-11 07:33:51

Python 的 *.py 文件只是一个文本文件,您可以在其中编写一些代码行。当您尝试使用“python filename.py”执行此文件时,

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

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

一旦生成了 *.pyc 文件,就不再需要 *.py 文件,除非您对其进行编辑。

Python's *.py file is just a text file in which you write some lines of code. When you try to execute this file using say "python filename.py"

This command invokes Python Virtual Machine. Python Virtual Machine has 2 components: "compiler" and "interpreter". Interpreter cannot directly read the text in *.py file, so this text is first converted into a byte code which is targeted to the PVM (not hardware but PVM). PVM executes this byte code. *.pyc file is also generated, as part of running it which performs your import operation on file in shell or in some other file.

If this *.pyc file is already generated then every next time you run/execute your *.py file, system directly loads your *.pyc file which won't need any compilation(This will save you some machine cycles of processor).

Once the *.pyc file is generated, there is no need of *.py file, unless you edit it.

挥剑断情 2024-09-11 07:33:51

太棒了;它是从源代码转换而来的代码,Python VM 对其进行解释并执行。

自下而上的理解:任何程序的最后阶段都是在硬件/机器上运行/执行程序的指令。以下是执行之前的阶段:

  1. 正在执行/在 CPU 上运行

  2. 将字节码转换为机器代码

    • 机器代码是转换的最后阶段。

    • 在 CPU 上执行的指令以机器代码给出。机器代码可以由CPU直接执行

  3. 字节码转换为机器代码。

    • 字节码是一个中等阶段。为了效率,可以跳过它,但会牺牲可移植性
  4. 源代码转换为字节码。

    • 源代码是人类可读代码。这是在 Pycharm 等 IDE(代码编辑器)上使用的内容。

现在是实际情节。执行任何这些阶段时有两种方法:一次性转换[或执行]代码(又名编译)和逐行转换[或执行]代码(又名解释< /强>)。

  • 例如,我们可以将源代码编译为字节码,将字节码编译为机器代码,解释机器代码以供执行。

  • 为了提高效率,某些语言的实现会跳过第 3 阶段,即将源代码编译为机器代码,然后解释机器代码来执行。

  • 一些实现会跳过所有中间步骤并直接解释源代码来执行。

  • 现代语言通常涉及编译和解释

  • 例如,JAVA将源代码编译为字节码[这就是JAVA源代码的存储方式,作为字节码,将字节码编译为机器代码[使用JVM],并解释机器代码以执行。 [因此,对于不同的操作系统,JVM 的实现方式有所不同,但相同的 JAVA 源代码可以在安装了 JVM 的不同操作系统上执行。]

  • 例如,Python,将源代码编译为字节码 [通常以 .pyc 文件形式存在附带.py源代码],将字节码编译为机器代码[由PVM等虚拟机完成,结果是可执行文件],解释机器代码/可执行文件以执行。

  • 什么时候我们可以说一种语言是解释型或编译型的?

    • 答案是通过研究执行中使用的方法。如果它一次执行所有机器代码(==编译),那么它是一种编译语言。另一方面,如果它逐行执行机器代码(==interpret),那么它就是一种解释语言。
  • 因此,JAVA和Python都是解释性语言。

  • 由于第三阶段(即将字节码转换为机器代码),可能会发生混乱。通常,这是使用称为虚拟机的软件来完成的。之所以会出现这种混乱,是因为虚拟机的行为就像一台机器,但实际上不是!引入虚拟机是为了可移植性,在任何真实机器上拥有虚拟机将允许我们执行相同的源代码。大多数虚拟机(第三阶段)使用的方法是编译,因此有些人会说它是一种编译语言。对于虚拟机的重要性,我们经常说此类语言既是编译型又是解释型

tldr; it's a converted code from the source code, which the python VM interprets for execution.

Bottom-up understanding: the final stage of any program is to run/execute the program's instructions on the hardware/machine. So here are the stages preceding execution:

  1. Executing/running on CPU

  2. Converting bytecode to machine code.

    • Machine code is the final stage of conversion.

    • Instructions to be executed on CPU are given in machine code. Machine code can be executed directly by CPU.

  3. Converting Bytecode to machine code.

    • Bytecode is a medium stage. It could be skipped for efficiency, but sacrificing portability.
  4. Converting Source code to bytecode.

    • Source code is a human readable code. This is what is used when working on IDEs (code editors) such as Pycharm.

Now the actual plot. There are two approaches when carrying any of these stages: convert [or execute] a code all at once (aka compile) and convert [or execute] the code line by line (aka interpret).

  • For example, we could compile a source code to bytecode, compile bytecode to machine code, interpret machine code for execution.

  • Some implementations of languages skip stage 3 for efficiency, i.e. compile source code into machine code and then interpret machine code for execution.

  • Some implementations skip all middle steps and interpret the source code directly for execution.

  • Modern languages often involve both compiling an interpreting.

  • JAVA for example, compiles source code to bytecode [that is how JAVA source is stored, as a bytecode, compile bytecode to machine code [using JVM], and interpret machine code for execution. [Thus JVM is implemented differently for different OSs, but the same JAVA source code could be executed on different OS that have JVM installed.]

  • Python for example, compile source code to bytecode [usually found as .pyc files accompanying the .py source codes], compile bytecode to machine code [done by a virtual machine such as PVM and the result is an executable file], interpret the machine code/executable for execution.

  • When can we say that a language is interpreted or compiled?

    • The answer is by looking into the approach used in execution. If it executes the machine code all at once (== compile), then it's a compiled language. On the other hand, if it executes the machine code line-by-line (==interpret) then it's an interpreted language.
  • Therefore, JAVA and Python are interpreted languages.

  • A confusion might occur because of the third stage, that's converting bytecode to machine code. Often this is done using a software called a virtual machine. The confusion occurs because a virtual machine acts like a machine, but it's actually not! Virtual machines are introduced for portability, having a VM on any REAL machine will allow us to execute the same source code. The approach used in most VMs [that's the third stage] is compiling, thus some people would say it's a compiled language. For the importance of VMs, we often say that such languages are both compiled and interpreted.

墟烟 2024-09-11 07:33:51

Python 代码经历两个阶段。第一步将代码编译成 .pyc 文件,这实际上是字节码。然后使用 CPython 解释器解释这个 .pyc 文件(字节码)。请参阅链接。这里用简单的术语解释了代码编译和执行的过程。

Python code goes through 2 stages. First step compiles the code into .pyc files which is actually a bytecode. Then this .pyc file(bytecode) is interpreted using CPython interpreter. Please refer to this link. Here process of code compilation and execution is explained in easy terms.

过期情话 2024-09-11 07:33:51

语言规范与语言实现的重要区别是:

  • 语言规范只是一个具有语言形式规范的文档,具有上下文无关的语法和语义规则的定义(如指定原始类型和范围动态)。
  • 语言实现只是一个按照语言规范实现语言使用的程序(编译器)。

任何编译器都由两个独立的部分组成:前端和后端。前端接收源代码,对其进行验证并将其转换为中间代码。之后,后端将其转换为机器代码以在物理机或虚拟机中运行。
解释器是一个编译器,但在这种情况下,它可以产生一种直接在虚拟机中执行中间代码的方式。
要执行Python代码,必须将代码转换为中间代码,然后将代码“组装”为可以存储在file.pyc中的字节码,因此不需要每次运行程序时都编译程序的模块。
您可以使用以下方式查看此汇编的Python代码:

from dis import dis
def a(): pass

dis(a)

任何人都可以构建Python语言的静态二进制编译器,就像可以构建< a href="https://stackoverflow.com/a/584720/4086871">C 语言解释器。有一些工具(lex/yacc)可以简化和自动化构建编译器的过程。

Its important distinguish language specification from language implementations:

  • Language specification is just a document with the formal specification of the language, with its context free grammar and definition of the semantic rules (like specifying primitive types and scope dynamics).
  • Language implementation is just a program (a compiler) that implement the use of the language according to its specification.

Any compiler consists of two independent parts: a frontend and backend. The frontend receives the source code, validate it and translate it into an intermediate code. After that, a backend translate it to machine code to run in a physical or a virtual machine.
An interpreter is a compiler, but in this case it can produce a way of executing the intermediate code directly in a virtual machine.
To execute python code, its necessary transform the code in a intermediate code, after that the code is then "assembled" as bytecode that can be stored in a file.pyc, so no need to compile modules of a program every time you run it.
You can view this assembled python code using:

from dis import dis
def a(): pass

dis(a)

Anyone can build a Compiler to static binary in Python language, as can build an interpreter to C language. There are tools (lex/yacc) to simplify and automate the proccess of building a compiler.

别忘他 2024-09-11 07:33:51

机器不理解英语或任何其他语言,它们只理解字节码,必须对其进行编译(例如,C/C++、Java)或解释(例如,Ruby、Python),.pyc 是 .pyc 的缓存版本字节码。
https://www.geeksforgeeks.org/difference- Between-compiled -和解释语言/
以下是编译语言与解释语言之间的区别的快速阅读,TLDR 是解释语言,不要求您在运行时之前编译所有代码,因此大多数时候它们对输入等并不严格。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文