Python vs Cpython

K D*_*awG 397 python cpython

什么是关于Python和CPython (Jython,IronPython)的所有这些大惊小怪,我不明白:

python.org提到CPython是:

Python的"传统"实现(绰号CPython)

另一个Stack Overflow问题提到:

CPython是Python的默认字节码解释器,用C语言编写.

老实说,我没有得到这两个解释实际上意味着什么,但我认为,如果我使用CPython,这意味着当我运行示例python代码时,它将它编译为C语言,然后执行它就好像它是C码

那么CPython究竟是什么呢?与python相比它有何不同?我是否应该使用CPython而不是Python,如果有的话,它有什么优势呢?

Mar*_*ers 623

那么CPython是什么?

CPython是最初的 Python实现.这是您从Python.org下载的实现.人们将其称为CPython,以区别于其他后来的Python实现,并将语言引擎的实现与Python 编程语言本身区分开来.

后半部分是你的困惑所在; 你需要将Python-the-language与运行 Python代码的任何东西分开.

CPython 恰好用C实现.这只是一个实现细节,真的.CPython将您的Python代码编译为字节码(透明地)并在评估循环中解释该字节码.

CPython也是第一个实现新功能的人; Python-the-language开发使用CPython作为基础; 其他实现如下.

Jython等怎么样?

Jython,IronPythonPyPy是Python编程语言的当前"其他"实现; 它们分别在Java,C#和RPython(Python的一个子集)中实现.Jython将您的Python代码编译为Java字节码,因此您的Python代码可以在JVM上运行.IronPython允许您在Microsoft CLR上运行Python .PyPy是在Python的(子集)中实现的,它允许您比CPython更快地运行Python代码,这应该让您大吃一惊.:-)

实际编译为C

因此CPython的不自行翻译您的Python代码到C.相反,它运行一个解释器循环.还有一个项目不会翻译的Python上下的代码转换为C,而被称为用Cython.用Cython增加了一些扩展Python语言,并让您编译代码,以C扩展,即插入代码 CPython的解释.

  • 我认为值得一提的是,理论上,可以使用任何实现运行python脚本,并且运行脚本的结果应该相同. (77认同)
  • 我说,"PyPy比CPython更快"是有点危险的.这里有一个非常好的答案:http://stackoverflow.com/questions/18946662/why-shouldnt-i-use-pypy-over-cpython-if-pypy-is-6-3-times-faster ?RQ = 1 (7认同)
  • 事实上,根据您正在进行的项目,在多个实现上测试和分析Python代码可能是个好主意.之前曾参与过Java + Jython项目,你可能会遇到很多惊喜,因为开发人员还没有在这个平台上测试过他们的libs. (3认同)
  • 对 IronPython 感到很兴奋......直到我看到它只支持 Python 2.x。 (2认同)
  • 我真的认为这个命名有问题,因为当你去python.org下载Python时,你被告知你正在下载Python(甚至文件包被命名为Python),但是你下载的是CPython而不是Python (因为Python“不存在”,它是一种语言,而不是一种实现)。我不明白为什么他们需要做得这么复杂。如果必须明确参考实现是 CPython,那么就将其称为 CPython,而不是 Python。我必须搜索它才能了解这是关于什么的。 (2认同)

jam*_*lak 80

您需要区分语言和实现.Python是一种语言,

根据维基百科,"编程语言是编写程序的符号,它是计算或算法的规范".这意味着它只是编写代码的规则和语法.另外,我们有一个编程语言实现,在大多数情况下,它是实际的解释器或编译器.

Python是一种语言.CPython是C中Python的实现.Jython是Java中的实现,依此类推.

总结一下:您已经在使用CPython(如果您从此处下载).

  • CPython 是 Python 在 C 中的实现。C 也是一种编程语言,是计算或算法的规范。所以我不明白他们在 CPython 中使用什么 C 实现? (4认同)
  • 为什么对 Cpython 有如此多的强调。即:我们听不到 Cc++ 或 CJava 甚至 CSwift。或者我错过了什么? (3认同)
  • 您应该阅读Martijn Pieters的帖子"CPython本身不会将您的Python代码转换为C语言.它会运行一个解释器循环.有一个项目可以将Python-ish代码转换为C,这就是所谓的Cython" (2认同)
  • @Suhaib:他们确实如此,在Java世界中,人们有HotSpot,OpenJDK,IBM J9 JDK,Azul。它们通常更精确,即您不会真正看到“安装Java”,而是“安装兼容的Java 8 JDK,例如Oracle JDK 8”。在JavaScript世界中,您有node.js,V8等。您是“安装node.js”,而不是“安装JavaScript”,对吗?但是在Python世界中,通常只是说“安装Python 3.6”并完成操作,这是指语言规范,而不是特定的运行时。 (2认同)

deb*_*yan 53

由于Python是开源的,这就是为什么我们可以根据我们的要求定制Python。定制后,我们可以根据需要命名该版本。这就是为什么有多种 Python 风格可供选择。每种风味都是 Python 的定制版本,以满足特殊要求。这类似于 UNIX 有多种风格的事实,例如 Ubuntu、Linux、RedHat Linux 等。以下是 python 的一些风格:

CPython

我们从 python.org 下载的python 编程语言的默认实现,由 python 软件基金会提供。它是用 C 和 python 编写的。它不允许我们编写任何C代码,只允许编写Python代码。CPython 既可以称为解释器,也可以称为编译器,因为这里我们的python 代码首先被编译为 python 字节码,然后字节码被 PVM 或 Python 虚拟机解释为特定于平台的操作。请记住,解释器已经预定义了语言语法,这就是为什么它不需要翻译成低级机器代码。这里解释器只是在运行时动态执行字节码并产生特定于平台的操作。

cpython 中的代码执行

旧版本的 JavaScript、Ruby、Php 是完全解释型语言,因为它们的解释器会直接将每一行源代码翻译为特定于平台的操作,不涉及字节码。Java、Python、C++ (.net)、C# 中存在字节码,用于将语言与执行环境解耦,即为了可移植性,编写一次,随处运行。自 2008 年以来,Google Chrome 的 V8 JavaScript 引擎推出了 JavaScript 即时编译器。它像解释器一样逐行执行 JavaScript 代码,以减少启动时间,但如果遇到重复执行代码行的热点部分,则使用基线或优化编译器优化该代码。

Cython

Cython 是一种编程语言,是 python 和 C 的超集。它是用 C 和 python 编写的。它旨在通过 python 语法和可选的 C 语法提供类似 C 的性能。Cython 是一种编译语言,因为它生成 C 代码并由 C 编译器编译。我们可以在 Cython 中编写与默认 python 或 CPython 类似的代码区别在于:

  • Cython 允许我们编写可选的附加 C 代码,并且,
  • 在 Cython 中,我们的python 代码在内部转换为 C 代码,以便可以由 C 编译器编译。尽管 Cython 的执行速度明显加快,但仍达不到原始 C语言的执行速度。这是因为 Cython 必须调用 CPython 解释器和 CPython 标准库来理解编写的 CPython 代码

在此输入图像描述

JPython / Jython

python编程语言的 Java 实现。它是用 Java 和 python 编写的。这里,我们的python 代码首先被编译为 Java 字节码,然后该字节码被 JVM 或 Java 虚拟机解释为特定于平台的操作。这类似于 Java 代码的执行方式:Java 代码首先被编译为中间字节码,然后由 JVM 将字节码解释为特定于平台的操作

PyPy

Python编程语言的 RPython 实现。它是用名为 Restricted Python (RPython) 的 Python 受限子集编写的PyPy 比 CPython 运行得更快,因为为了解释字节码,PyPy 有一个即时编译器(解释器 + 编译器),而 CPython 有一个解释器。因此,PyPy 中的 JIT 编译器可以像解释器一样逐行执行 Python 字节码,以减少启动时间,但如果遇到重复执行代码行的热点部分,则使用Baseline or Optimizing Compiler.

pypy代码执行

JIT编译器简而言之Python中的编译器将我们的高级源代码翻译成字节码执行字节码,一些实现具有普通的解释器,一些实现具有即时编译器。要执行一个运行一百万次的循环,即一段非常热的代码,最初解释器将运行它一段时间,然后MonitorJIT 编译器将监视该代码。然后,当它重复几次时,即代码变得温暖*,JIT 编译器将将该代码发送到该代码Baseline Compiler,该代码将根据观看代码时收集的数据对变量类型等做出一些假设。Monitor从下一次迭代开始,如果假设被证明是有效的,则无需将字节码重新翻译为机器代码,即可以跳过步骤以加快执行速度。如果代码重复很多次,即代码变得非常热,那么 JIT 编译器将将该代码发送到该代码,该代码Optimizing Compiler将做出更多假设并跳过更多步骤以实现快速执行。

JIT 编译器的缺点:分析代码时初始执行速度较慢,如果假设结果为假,则优化的编译代码将被丢弃,即DeoptimizationBailing out发生这可能会使代码执行速度变慢,尽管 JIT 编译器对优化/反优化周期有限制。发生一定次数的去优化后,JIT 编译器就不再尝试优化。而普通的 Interpreter每次迭代中都会重复将字节码转换为机器代码,从而需要更多时间来完成一个运行数百万次的循环

IronPython

python 的 C# 实现,针对 .NET 框架

Ruby Python

适用于 Ruby 平台

Anaconda Python

用于科学计算的 Python 和 R 编程语言的分发,例如数据科学、机器学习、人工智能、深度学习、处理大量数据等。大量的库,例如 scikit-learn、tensorflow、pytorch、numba、pandas、jupyter 、numpy、matplotlib 等可用于此软件包

Stackless

Python 并发

为了测试每个实现的速度,我们编写了一个程序,使用 N 值 50,000 调用Integrate_f 500次,并记录几次运行的执行时间。下表显示了基准测试结果:

执行 执行时间(秒) 加速
CPython 9.25
CPython + Cython 0.21 44x
吡啶 0.57 16x


sha*_*aan 28

文章详细地介绍了Python中的不同实现之间的区别.就像文章所说:

首先要意识到'Python'是一个界面.有一个Python应该做什么以及它应该如何表现的规范(与任何接口一样).并且有多种实现(与任何接口一样).

要实现的第二件事是"解释"和"编译"是实现的属性,而不是接口.


Vij*_*mar 27

即使我有同样的问题,了解CPython,JPython,IronPython,PyPy是如何彼此不同的.

所以,在我开始解释之前,我愿意清除三件事:

  1. Python:它是一种语言,它只表示/描述如何向解释器(接受你的python代码的程序)传达/表达自己.
  2. 实现:完全是关于如何编写解释器,特别是以什么语言最终完成的工作.
  3. 字节码:由程序(通常称为虚拟机)处理的代码,而不是由"真实"计算机机器(硬件处理器)处理的代码.

CPython是实现,它是用C语言编写的.它最终生成字节码(基于堆栈机器的指令集),这是特定于Python的,然后执行它.将Python代码转换为字节码的原因是因为如果它看起来像机器指令,则更容易实现解释器.但是,在执行Python代码之前没有必要生成一些字节码(但CPython确实产生了).

如果你想查看CPython的字节码,那么你可以.以下是您的方法:

>>> def f(x, y):                # line 1
...    print("Hello")           # line 2
...    if x:                    # line 3
...       y += x                # line 4
...    print(x, y)              # line 5
...    return x+y               # line 6
...                             # line 7
>>> import dis                  # line 8
>>> dis.dis(f)                  # line 9
  2           0 LOAD_GLOBAL              0 (print)
              2 LOAD_CONST               1 ('Hello')
              4 CALL_FUNCTION            1
              6 POP_TOP

  3           8 LOAD_FAST                0 (x)
             10 POP_JUMP_IF_FALSE       20

  4          12 LOAD_FAST                1 (y)
             14 LOAD_FAST                0 (x)
             16 INPLACE_ADD
             18 STORE_FAST               1 (y)

  5     >>   20 LOAD_GLOBAL              0 (print)
             22 LOAD_FAST                0 (x)
             24 LOAD_FAST                1 (y)
             26 CALL_FUNCTION            2
             28 POP_TOP

  6          30 LOAD_FAST                0 (x)
             32 LOAD_FAST                1 (y)
             34 BINARY_ADD
36 RETURN_VALUE
Run Code Online (Sandbox Code Playgroud)

现在,我们来看看上面的代码.第1行到第6行是函数定义.在第8行中,我们导入'dis'模块,该模块可用于查看由CPython(解释器)生成的中间Python字节码(或者可以说是Python字节码的反汇编程序).

注意:我从#python IRC频道获得了此代码的链接:https://gist.github.com/nedbat/e89fa710db0edfb9057dc8d18d979f9c

然后,有Jython,它是用Java编写的,最终生成Java字节码.Java字节代码在Java Runtime Environment上运行,Java Runtime Environment是Java虚拟机(JVM)的一种实现.如果这令人困惑,那么我怀疑你不知道Java是如何工作的.通俗地说,Java(语言,而不是编译器)代码由Java编译器获取并输出只能使用JRE运行的文件(Java字节代码).这样做是为了一旦Java代码被编译,那么它就可以以Java字节代码格式移植到其他机器,这只能由JRE运行.如果这仍然令人困惑,那么您可能需要查看此网页.

在这里,您可能会问CPython的字节码是否像Jython一样可移植,我怀疑不是.CPython实现中生成字节码特定于该解释器,以便于进一步执行代码(我还怀疑,这样的中间字节码生成,只是为了便于处理在许多其他解释器中完成).

因此,在Jython中,当您编译Python代码时,最终会得到Java字节代码,它可以在JVM上运行.

类似地,IronPython(用C#语言编写)将Python代码编译为公共语言运行时(CLR),与Microsoft开发的JVM相比,这是一种类似的技术.

  • CPython(实现)也执行它,这意味着它包含将字节代码转换为机器代码的功能。 (4认同)
  • 谢谢详细解释!!这意味着 CPython 负责将 Python 代码转换为字节码并将字节码解释为机器码?简而言之,CPython 是编译器(用于 Python 到字节码)和 Python 虚拟机(用于字节码到机器码)?与 .Net 相比,有 C# Compiler 可以将 C# 转换为 MSIL 和 CLR 可以将 MSIL 转换为机器代码。 (3认同)

orl*_*nko 19

Python是一种语言:一组可用于编写程序的规则.这种语言有几种实现方式.

无论你采取什么样的实现,它们都做同样的事情:获取程序的文本并解释它,执行它的指令.他们都没有将您的代码编译成C或任何其他语言.

CPython是用C编写的原始实现.("CPython"中的"C"部分指的是用于编写Python解释器本身的语言.)

Jython是相同的语言(Python),但使用Java实现.

IronPython解释器是用C#编写的.

还有PyPy - 一个用Python编写的Python解释器.你的选择:)


Abh*_*jit 7

implementation意味着使用什么语言来实现Python,而不是如何实现python Code.使用CPython的优点是C Run-time的可用性以及与C/C++的轻松集成.

所以CPython最初是用C.原始实现还有其他分支,使Python能够利用Java(JYthon)或.NET Runtime(IronPython).

根据您使用的实现,库可用性可能会有所不同,例如Ctypes在Jython中不可用,因此任何使用ctypes的库都无法在Jython中使用.同样,如果要使用Java类,则无法直接从CPython执行此操作.你需要一个胶水(JEPP)或需要使用Jython(Python的Java实现)


The*_*hMe 6

您应该知道 CPython 并不真正支持多线程(它支持,但不是最佳的),因为全局解释器锁。它也没有递归优化机制,并且有许多其他实现和库试图填补的其他限制。

你应该看看python wiki 上的这个页面

看看这个页面上的代码片段,它会让你很好地了解解释器是什么。

  • CPython 支持多线程,但 GIL 很难利用多核或 CPU。这与根本不支持多线程并不完全相同。 (20认同)