标签归档:interpreted-language

是Python解释,编译还是两者兼而有之?

问题:是Python解释,编译还是两者兼而有之?

据我了解:

一个解释语言是高级语言运行和由解释器执行(程序将高级语言转换成机器代码,然后执行)在旅途中; 它一次只处理一点程序。

编译语言是一种高级语言,其代码由编译器(其高级语言转换成机器代码的程序)首先被转换为机器代码,然后执行由执行器(另一个程序用于运行代码)。

如果我的定义错误,请纠正我。

现在回到Python,对此我有些困惑。到处都可以了解到Python是一种解释语言,但是它会解释为某些中间代码(例如字节代码或IL),而不是机器代码。那么,哪个程序执行IM代码?请帮助我了解如何处理和运行Python脚本。

From my understanding:

An interpreted language is a high-level language run and executed by an interpreter (a program which converts the high-level language to machine code and then executing) on the go; it processes the program a little at a time.

A compiled language is a high-level language whose code is first converted to machine-code by a compiler (a program which converts the high-level language to machine code) and then executed by an executor (another program for running the code).

Correct me if my definitions are wrong.

Now coming back to Python, I am bit confused about this. Everywhere you learn that Python is an interpreted language, but it’s interpreted to some intermediate code (like byte-code or IL) and not to the machine code. So which program then executes the IM code? Please help me understand how a Python script is handled and run.


回答 0

首先,解释/编译不是语言的属性,而是实现的属性。对于大多数语言,大多数(如果不是全部)实现都归为一类,因此可以省去几个词来说明该语言也可以解释/编译,但这仍然是一个重要的区别,因为这有助于理解,而且语言也很多具有两种可用的实现(主要在功能语言领域,请参见Haskell和ML)。另外,有些C解释器和项目试图将Python的子集编译为C或C ++代码(然后编译为机器代码)。

其次,编译不限于提前编译为本机代码。更一般而言,编译器是将一种编程语言的程序转换为另一种编程语言的程序的程序(可以说,如果应用了重要的转换,甚至可以使编译器使用相同的输入和输出语言)。而且,JIT编译器可以在运行时编译为本地机器代码,这可以使速度与提前编译非常接近甚至更好(取决于基准和所比较实现的质量)。

但是要停止挑剔并回答您要问的问题:实际上(阅读:使用某种流行和成熟的实现),Python被编译了。不会提前编译为机器代码(即受限制和错误的“编译”,但是很常见的定义),“仅”编译为字节码,但它仍然具有至少一些优点。例如,该语句a = b.c()被编译为字节流,当“反汇编”时,该字节流看起来像load 0 (b); load_str 'c'; get_attr; call_function 0; store 1 (a)。这是一种简化,实际上它的可读性较低,而底层则更高级-您可以尝试使用标准库dis模块并查看实际交易的外观。

与参考实现(CPython)一样,该字节码也可以被解释(请注意,直接解释和首先编译为某种中间表示并对其进行解释之间,在理论上和实际性能上都有区别),或者在解释和编译为与PyPy一样,在运行时优化了机器代码。

First off, interpreted/compiled is not a property of the language but a property of the implementation. For most languages, most if not all implementations fall in one category, so one might save a few words saying the language is interpreted/compiled too, but it’s still an important distinction, both because it aids understanding and because there are quite a few languages with usable implementations of both kinds (mostly in the realm of functional languages, see Haskell and ML). In addition, there are C interpreters and projects that attempt to compile a subset of Python to C or C++ code (and subsequently to machine code).

Second, compilation is not restricted to ahead-of-time compilation to native machine code. A compiler is, more generally, a program that converts a program in one programming language into a program in another programming language (arguably, you can even have a compiler with the same input and output language if significant transformations are applied). And JIT compilers compile to native machine code at runtime, which can give speed very close to or even better than ahead of time compilation (depending on the benchmark and the quality of the implementations compared).

But to stop nitpicking and answer the question you meant to ask: Practically (read: using a somewhat popular and mature implementation), Python is compiled. Not compiled to machine code ahead of time (i.e. “compiled” by the restricted and wrong, but alas common definition), “only” compiled to bytecode, but it’s still compilation with at least some of the benefits. For example, the statement a = b.c() is compiled to a byte stream which, when “disassembled”, looks somewhat like load 0 (b); load_str 'c'; get_attr; call_function 0; store 1 (a). This is a simplification, it’s actually less readable and a bit more low-level – you can experiment with the standard library dis module and see what the real deal looks like. Interpreting this is faster than interpreting from a higher-level representation.

That bytecode is either interpreted (note that there’s a difference, both in theory and in practical performance, between interpreting directly and first compiling to some intermediate representation and interpret that), as with the reference implementation (CPython), or both interpreted and compiled to optimized machine code at runtime, as with PyPy.


回答 1

CPU实际上只能理解机器代码。对于解释程序,解释器的最终目标是将程序代码“解释”为机器代码。但是,现代解释型语言通常效率太低,因此不能直接解释人类代码。

Python解释器首先读取人工代码并将其优化为某些中间代码,然后再将其解释为机器代码。这就是为什么您始终需要另一个程序来运行Python脚本的原因,而在C ++中,您可以直接运行代码的已编译可执行文件。例如,c:\Python27\python.exe/usr/bin/python

The CPU can only understand machine code indeed. For interpreted programs, the ultimate goal of an interpreter is to “interpret” the program code into machine code. However, usually a modern interpreted language does not interpret human code directly because it is too inefficient.

The Python interpreter first reads the human code and optimizes it to some intermediate code before interpreting it into machine code. That’s why you always need another program to run a Python script, unlike in C++ where you can run the compiled executable of your code directly. For example, c:\Python27\python.exe or /usr/bin/python.


回答 2

答案取决于正在使用哪种python实现。如果使用的是CPython(Python的标准实现)或Jython(目标是与Java编程语言集成),则首先将其翻译为bytecode,然后根据所使用的python的实现,将此bycode定向到相应的用于解释的虚拟机。用于CPython的PVM(Python虚拟机)和用于Jython的JVM(Java虚拟机)。

但是可以说您正在使用PyPy,这是另一种标准的CPython实现。它将使用即时编译器

The answer depends on what implementation of python is being used. If you are using lets say CPython (The Standard implementation of python) or Jython (Targeted for integration with java programming language)it is first translated into bytecode, and depending on the implementation of python you are using, this bycode is directed to the corresponding virtual machine for interpretation. PVM (Python Virtual Machine) for CPython and JVM (Java Virtual Machine) for Jython.

But lets say you are using PyPy which is another standard CPython implementation. It would use a Just-In-Time Compiler.


回答 3

根据Python的官方网站,它是一种解释语言。

https://www.python.org/doc/essays/blurb/

Python是一种解释型,面向对象的高级编程语言。

由于没有编译步骤…

可以使用Python解释器和广泛的标准库…

相反,当解释器发现错误时,它将引发异常。当程序未捕获异常时,解释器将打印堆栈跟踪。

According to the official Python site, it’s interpreted.

https://www.python.org/doc/essays/blurb/

Python is an interpreted, object-oriented, high-level programming language…

Since there is no compilation step …

The Python interpreter and the extensive standard library are available…

Instead, when the interpreter discovers an error, it raises an exception. When the program doesn’t catch the exception, the interpreter prints a stack trace.


回答 4

是的,它既是编译语言,又是解释语言。 那为什么我们通常将其称为解释语言呢?

看看它是如何被编译和解释的?

首先,我想告诉您,如果您来自Java世界,那么您会更喜欢我的回答。

在Java中,源代码首先通过javac编译器转换为字节代码,然后定向到JVM(负责生成用于执行目的的本机代码)。现在,我想向您展示我们将Java称为编译语言,因为我们可以看到它确实可以编译源代码并通过以下方式提供.class文件(除了字节码外):

javac Hello.java ——->产生Hello.class文件

java Hello ——–>将字节码定向到JVM以执行

python发生了同样的事情,即首先将源代码通过编译器转换为字节码,然后定向到PVM(负责生成用于执行目的的本机代码)。现在,我想向您展示我们通常将Python称为一种解释语言,因为编译是在后台进行的, 并且当我们通过以下方式运行python代码时:

python Hello.py ——->直接执行代码,我们可以看到输出证明该代码在语法上是正确的

@ python Hello.py看起来像直接执行,但实际上它首先生成由解释器解释的字节码,以产生用于执行目的的本机代码。

CPython-负责编译和解释。

如果需要更多详细信息,请查看以下几行

正如我提到的那样,CPython会编译源代码,但是实际的编译是在cython的帮助下发生的,然后解释是在CPython的帮助下发生的

现在让我们谈谈即时编译器在Java和Python中的作用

在JVM中,存在Java解释器,该解释器逐行解释字节码以获取用于执行目的的本机代码,但是当Java字节码由解释器执行时,执行总是较慢。那么解决方案是什么?解决方案是即时编译器,该编译器生成的本机代码可以比解释的快得多地执行。一些JVM供应商使用Java解释器,一些则使用即时编译器。参考:点击这里

在python中绕过解释器以实现快速执行,请使用另一个python实现(PyPy)而不是CPython点击此处查看python的其他实现,包括PyPy

Yes, it is both compiled and interpreted language. Then why we generally call it as interpreted language?

see how it is both- compiled and interpreted?

First of all I want to tell that you will like my answer more if you are from the Java world.

In the Java the source code first gets converted to the byte code through javac compiler then directed to the JVM(responsible for generating the native code for execution purpose). Now I want to show you that we call the Java as compiled language because we can see that it really compiles the source code and gives the .class file(nothing but bytecode) through:

javac Hello.java ——-> produces Hello.class file

java Hello ——–>Directing bytecode to JVM for execution purpose

The same thing happens with python i.e. first the source code gets converted to the bytecode through the compiler then directed to the PVM(responsible for generating the native code for execution purpose). Now I want to show you that we usually call the Python as an interpreted language because the compilation happens behind the scene and when we run the python code through:

python Hello.py ——-> directly excutes the code and we can see the output provied that code is syntactically correct

@ python Hello.py it looks like it directly executes but really it first generates the bytecode that is interpreted by the interpreter to produce the native code for the execution purpose.

CPython– Takes the responsibility of both compilation and interpretation.

Look into the below lines if you need more detail:

As I mentioned that CPython compiles the source code but actual compilation happens with the help of cython then interpretation happens with the help of CPython

Now let’s talk a little bit about the role of Just-In-Time compiler in Java and Python

In JVM the Java Interpreter exists which interprets the bytecode line by line to get the native machine code for execution purpose but when Java bytecode is executed by an interpreter, the execution will always be slower. So what is the solution? the solution is Just-In-Time compiler which produces the native code which can be executed much more quickly than that could be interpreted. Some JVM vendors use Java Interpreter and some use Just-In-Time compiler. Reference: click here

In python to get around the interpreter to achieve the fast execution use another python implementation(PyPy) instead of CPython. click here for other implementation of python including PyPy.


回答 5

如果(您知道Java){

Python代码会像java一样转换为字节码。
每当您尝试访问该字节码时,都会再次执行该字节码。

}其他{

Python代码最初被转换为称为字节码的字节
,它与机器语言非常接近,但与实际的机器代码并不相近,
因此每次我们访问或运行它时,字节码都会再次执行

}

If ( You know Java ) {

Python code is converted into bytecode like java does.
That bytecode is executed again everytime you try to access it.

} else {

Python code is initially traslated into something called bytecode
that is quite close to machine language but not actual machine code
so each time we access or run it that bytecode is executed again

}


回答 6

几乎可以说Python是解释语言。但是我们在python中使用了一次编译过程的一部分,将完整的源代码转换为类似Java语言的字节代码。

Almost, we can say Python is interpreted language. But we are using some part of one time compilation process in python to convert complete source code into byte-code like java language.


回答 7

对于新手

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

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

例如,如果您有一个脚本文件abc.py导入了另一个模块xyz.py,则当您运行abc.py时,由于导入了xyz,将创建xyz.pyc,但是从abc开始将不创建abc.pyc文件。 py未导入。

For newbies

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.


回答 8

您编写的python代码将编译为python字节码,从而创建扩展名为.pyc的文件。如果进行编译,那么又一个问题是,为什么不编译语言。

请注意,这不是传统意义上的编译。通常,我们会说编译是采用高级语言并将其转换为机器代码。但这是各种汇编。编译成中间代码而不是机器代码(希望您现在就知道了)。

返回执行过程,然后在适当的虚拟机(在我们的示例中为CPython VM)中执行在编译步骤中创建的,在pyc文件中存在的字节码,然后使用时间戳记(称为幻数)来验证是否。 py文件是否更改,取决于创建的新pyc文件。如果pyc是当前代码,则只需跳过编译步骤。

The python code you write is compiled into python bytecode, which creates file with extension .pyc. If compiles, again question is, why not compiled language.

Note that this isn’t compilation in the traditional sense of the word. Typically, we’d say that compilation is taking a high-level language and converting it to machine code. But it is a compilation of sorts. Compiled in to intermediate code not into machine code (Hope you got it Now).

Back to the execution process, your bytecode, present in pyc file, created in compilation step, is then executed by appropriate virtual machines, in our case, the CPython VM The time-stamp (called as magic number) is used to validate whether .py file is changed or not, depending on that new pyc file is created. If pyc is of current code then it simply skips compilation step.


回答 9

Python(解释器)已编译

证明:如果包含语法错误,甚至不会编译您的代码。

范例1:

print("This should print") 
a = 9/0 

输出:

This should print
Traceback (most recent call last):
  File "p.py", line 2, in <module>
    a = 9/0
ZeroDivisionError: integer division or modulo by zero

代码已成功编译。第一行被执行(print)第二行抛出ZeroDivisionError(运行时错误)。

范例2:

print("This should not print")
/0         

输出:

  File "p.py", line 2
    /0
    ^
SyntaxError: invalid syntax

结论:如果您的代码文件不包含SyntaxError任何内容,则将在编译失败时执行。

Python(the interpreter) is compiled.

Proof: It won’t even compile your code if it contains syntax error.

Example 1:

print("This should print") 
a = 9/0 

Output:

This should print
Traceback (most recent call last):
  File "p.py", line 2, in <module>
    a = 9/0
ZeroDivisionError: integer division or modulo by zero

Code gets compiled successfully. First line gets executed (print) second line throws ZeroDivisionError (run time error) .

Example 2:

print("This should not print")
/0         

Output:

  File "p.py", line 2
    /0
    ^
SyntaxError: invalid syntax

Conclusion: If your code file contains SyntaxError nothing will execute as compilation fails.


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

问题:如果解释了Python,那么什么是.pyc文件?

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

这些从哪里来?

I’ve been given to understand that Python is an interpreted language…
However, when I look at my Python source code I see .pyc files, which Windows identifies as “Compiled Python Files”.

Where do these come in?


回答 0

它们包含字节码,这是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.


回答 1

我已经了解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”!-)


回答 2

没有所谓的解释语言。使用解释器还是编译器纯粹是实现的特征,与该语言绝对无关。

每种语言都可以由解释器或编译器实现。绝大多数语言至少每种类型都有一种实现。(例如,有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字节码,然后对其进行解释。
  • 无堆栈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.


回答 3

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

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.


回答 4

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

CPython将其源代码编译为“字节代码”,并且出于性能方面的考虑,只要源文件发生更改,它都会在文件系统上缓存该字节代码。由于可以绕过编译阶段,因此可以更快地加载Python模块。当您的源文件是foo.py时,CPython将字节代码缓存在源代码旁边的foo.pyc文件中。

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

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

欲获得更多信息:

参考:PEP3147
参考:“已编译” 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:

For more information:

ref:PEP3147
ref:“Compiled” Python files


回答 5

这是给初学者的,

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

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

举例来说,如果你有一个脚本文件abc.py是进口的另一个模块xyz.py,当你运行abc.pyxyz.pyc将被创建,因为XYZ是进口的,但没有abc.pyc文件将被创建以来的ABC。 py未导入。

如果您需要为未导入的模块创建.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


回答 6

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…


回答 7

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.


回答 8

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.