设为首页收藏本站

LUPA开源社区

 找回密码
 注册
文章 帖子 博客
LUPA开源社区 首页 业界资讯 技术文摘 查看内容

为什么有这么多 Python?

2013-9-29 09:56| 发布者: 红黑魂| 查看: 1575| 评论: 0|来自: 开源中国编译

摘要: Python是出类拔萃的然而,这是一句非常模棱两可的话。这里的"Python"到底指的是什么? 是Python的抽象接口吗?是Python的通用实现CPython吗(不要把CPython跟Cython搞混了)?亦或者指的完全是其他的东西呢 ...

Python是出类拔萃的

然而,这是一句非常模棱两可的话。这里的"Python"到底指的是什么? 是Python的抽象接口吗?

是Python的通用实现CPython吗(不要把CPython跟Cython搞混了)?亦或者指的完全是其他的东西呢?

可能我另外指的是Jython,或者IronPython,或者是PyPy。也或者转而谈论的又是RPython或者RubyPython

(这两者是完全不同的东西)。

上面提到的那些技术经常被提起和引用, 它们的使用目的和场景是完全不一样的

(至少,它们的操作方式是完全不一样的)


自从我使用Python工作以来,我已经用过了各种各样的.*ython工具了。但是直到最近我才花时间去理解到

底它们是干嘛的,它们是怎样工作的,为什么它们是不可或缺的。

在这篇文章里面,我会介绍各种Python的实现,最后以对PyPy的介绍结尾, 因为我个人认为它是Python的未来。

所有的都从理解什么是"Python"开始。

如果你对机器码,虚拟机之类的很熟了,你可以跳过开头,直接从 "即时编译: PyPy和它的未来" 这部分开始看起


Python是解释型的还是编译型的?

这是个Python新人都会迷惑的问题。

首先需要明了的是Python只是一个接口。有一个关于Python应该做什么以及怎么做的具体说明

(就像其他任何接口一样 ),并且对应的有很多具体的实现(也像其他接口一样)。

其次需要知道的是“解释型”和“编译型”是具体实现的特性,而不是接口的特性。

所以,这个问题本身就没有组织好。

Python是解释型还是编译型的?这个问题真的没有组织好。


对使用最广泛的实现(CPython:用C实现的,通常简单的说成Python,若你不知道我所说的这些,那很肯能你

在使用的就是CPython)而言,这个问题的答案是:解释型,但带有一些编译型特征。CPython把Python源码

*成字节码,之后再解释这些字节码,执行之。

*注意:这个编译不是通常意义上的编译。通常我们说的编译,是指把高级语言代码转换成机器码。但这里实际

上是一种种类的编译。(译者,这句话不是很懂,原文是it is a ‘compilation’ of sorts,不知作何解,求教各位读者。)

再详细看下上面的答案吧,这有助于我们理解本文中后面会讲到的几个概念。


字节码 vs. 机器码

了解字节码和机器码(或者native code)的区别是很重要的,最好的办法或许是看看例子:

  • C代码被编译成机器码,将在处理器上直接执行。每一条指令控制CPU工作。
  • Java代码被编译成字节码,将在Java虚拟机(JVM)这个抽象的计算机上执行。每一条指令由JVM处理,
  • JVM同计算机本身之间交互。

简而言之:机器码快的多,但字节码更易迁移,也更安全。


机器码随机器的变化而变化,但字节码在所有的机器上都是一样的。有人可能会认为机器码是对特定环境优化了的。

  1. 回到CPython,工具链的执行过程如下:
  2. CPython编译你的Python源代码,生成字节码。

字节码随后在CPython虚拟机上执行。

初学者常常因为看到.pyc文件而假设Python是编译型的。这也有一些合理性:.pyc文件正式之后要解释的字

节码文件。所以,你若之前运行过你的Python代码,生成了.pyc文件,再次运行时就要快得多,因为不需要

再次编译生成字节码了。


可选的虚拟机:Jython,IronPython等

正如我之前所述,Python有很多实现。前面也提到,CPython是最通用的。这是一个用C实现的,被认为是

”默认“的实现。

但其他的呢?其中最显赫的之一就是Jython,一个用Java实现的采用了JVM的实现。CPython生成在

CPython虚拟机上运行的字节码,而Jython生成在JVM上运行的java字节码(这同编译Java程序生成java字

节码的过程是一样的)。



”为啥你要用其他的实现?”,你可能会如此发问。好吧,对开发者而言,不同的实现对不同的技术难题的支持

程度不一样。


CPython中很容易为你的Python代码写C扩展,因为最终都是由C解释器执行的。另一方面,Jython则使得和

其他java程序共同工作很容易:无需其他工作,你就可导入任何Java类,在你的Jython程序中使用其他Java类

(题外话,若你没有认真思考,这一段会很难。此时我们已经在讨论把不同语言的代码混在一起,并编译成同

一程序。(Rostin 提出混合Fortran和C代码编程已经有一段时间了。所以,这并不新鲜,但仍然很酷。))

下面是一个例子,一段合法的Jython代码:

1[Java HotSpot(TM) 64-Bit Server VM (Apple Inc.)] on java1.6.0_51
2>>> from java.util import HashSet
3>>> s = HashSet(5)
4>>> s.add("Foo")
5>>> s.add("Bar")
6>>> s
7[Foo, Bar]

IronPython是另一很流行的Python 实现,完全用C#实现,针对.NET平台。她运行在可以叫做.NET虚拟机的

平台上,这是微软的 Common Language Runtime (CLR),同JVM相对应。


你可能会说,Jython:Java::IronPython:C#。它们各自运行在相同的虚拟机上,你能从你的IronPython中导入C#的

类,从你写的Jython代码中带入Java类,等等

你完全可以不用任何非CPython的实现就能完成你手上的任何工作。但是使用这些技术也是有很多的好处的,大部分取

决于你现在所使用的技术栈。 你使用了很多基于JVM的语言?Jython就是为你准备的。使用的都是.NET世界的语言?

那么你应该试试IronPython了(或许你已经在用了)



顺便说一下(尽管这不是使用不同的实现的理由),注意Python的各种实现在对待你的Python源码的时候所

做的处理方式是完全不一样的。然后这些差异是很小的,由于这些实现都在不停的发展改进中,随着时间的推

移,这些差异会慢慢融合和兼容。比如,IronPython默认情况下使用Unicode字符串,但是在2.x版本的

CPython中默认是ASCII字符串(如果使用了非ASCII字符串,会抛出一个UnicodeEncodeError错误),

但是在3.x版本里面CPythong已经默认支持Unicode字符串了。


即时编译: PyPy和它的未来

我们已经有了一个使用C写的Python实现,一个用Java写的,一个用C#写的。接下来就是:用Python写的

Python实现(有心人可能会注意这句话有点问题,是个死循环,^_^)

接下来我们看下什么地方容易搞混淆。首先,我们讨论下即时编译器JIT

JIT: 为什么会有这个?它的原理是什么?

大家都知道本地机器码的速度比字节码的速度快很多。那么,如果我们能将一些字节码直接编译成本地机器码再去

运行它会怎样呢?我们必须花费一些代价(比如时间)在编译字节码到本地机器码上,如果最终的运行时间更快,

那么这个代价就是值得的。这就是JIT编译器的动机,一种混合了解释器和编译器好处的技术。简单来讲,JIT就是

想通过编译技术提升脚本解释器系统的速度。


例如, 被JIT(及时编译)采用的通用方法:

  1. 标识被经常执行的字节码。
  2. 把其编译成本地的机器码。
  3. 缓存该结果。
  4. 当同样的的字节码再次被执行的时候,会取预编译的机器码,得到好处(例如速度提升)。

这是关于PyPy的用处: 把JIT代入Python语言 (参看前面成果的附录).当然也有其他目的: PyPy 目标是成为一个

跨平台,轻内存,支持stackless(译注:stackless为python提供微线程扩展,具有并发特性)。 但是及时编

译才是它真正的卖点。 基于一系列时间测试的平均, 据说性能上能提高6.27倍. 停一下, 看看下面这个由

PyPy Speed Center提供的图表:




酷毙

雷人

鲜花

鸡蛋

漂亮
  • 快毕业了,没工作经验,
    找份工作好难啊?
    赶紧去人才芯片公司磨练吧!!

最新评论

关于LUPA|人才芯片工程|人才招聘|LUPA认证|LUPA教育|LUPA开源社区 ( 浙B2-20090187 浙公网安备 33010602006705号   

返回顶部