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


当前回答

没有解释性语言这种东西。使用解释器还是编译器纯粹是实现的特性,与语言完全无关。

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

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."

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

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

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

不仅术语“解释语言”没有意义,即使你将其理解为“带有解释实现的语言”,这显然是不正确的。不管是谁告诉你的,显然他不知道自己在说什么。

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

其他回答

Python的*.py文件只是一个文本文件,您可以在其中编写一些代码行。当你试图使用"python filename。py"来执行这个文件时

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

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

一旦*。生成Pyc文件,不需要*.py文件,除非你编辑它。

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

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

语言规范只是带有语言正式规范的文档,具有上下文无关的语法和语义规则定义(如指定基本类型和作用域动态)。 语言实现只是一个程序(编译器),它根据语言的规范实现语言的使用。

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)

任何人都可以用Python语言构建静态二进制的编译器,就像可以构建C语言的解释器一样。有一些工具(lex/yacc)可以简化编译器的构建过程并使之自动化。

它们包含字节代码,Python解释器将源代码编译为字节代码。这段代码随后由Python的虚拟机执行。

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

Python是一种解释性语言,例如 而不是编译的 区别可能是模糊的,因为 字节码编译器的存在。 这意味着源文件可以 直接运行而不显式地运行 创建一个可执行文件,然后 运行。

tldr;它是从源代码转换而来的代码,python虚拟机将其解释为执行。

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

Executing/running on CPU 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. Converting Bytecode to machine code. Bytecode is a medium stage. It could be skipped for efficiency, but sacrificing portability. 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.

现在来看实际的情节。在进行这些阶段的任何一个阶段时,有两种方法:一次性转换[或执行]代码(又名编译)和逐行转换[或执行]代码(又名解释)。

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.