溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

困擾多年的問題,Python到底是語(yǔ)言,還是工具,哈佛教授完美詮釋

發(fā)布時(shí)間:2020-07-29 21:16:05 來(lái)源:網(wǎng)絡(luò) 閱讀:537 作者:眼淚你別問 欄目:編程語(yǔ)言

困擾多年的問題,Python到底是語(yǔ)言,還是工具,哈佛教授完美詮釋

然而,這是一句非常模棱兩可的話。這里的"Python"到底指的是什么? 是Python的抽象接口嗎?是Python的通用實(shí)現(xiàn)CPython嗎(不要把CPython跟Cython搞混了)?亦或者指的完全是其他的東西呢?可能我另外指的是Jython,或者IronPython,或者是PyPy。也或者轉(zhuǎn)而談?wù)摰挠质荝Python或者RubyPython(這兩者是完全不同的東西)。

上面提到的那些技術(shù)經(jīng)常被提起和引用, 它們的使用目的和場(chǎng)景是完全不一樣的(至少,它們的操作方式是完全不一樣的)

自從我使用Python工作以來(lái),我已經(jīng)用過了各種各樣的.*ython工具了。但是直到最近我才花時(shí)間去理解到底它們是干嘛的,它們是怎樣工作的,為什么它們是不可或缺的。

在這篇文章里面,我會(huì)介紹各種Python的實(shí)現(xiàn),最后以對(duì)PyPy的介紹結(jié)尾, 因?yàn)槲覀€(gè)人認(rèn)為它是Python的未來(lái)。

所有的都從理解什么是"Python"開始。

如果你對(duì)機(jī)器碼,虛擬機(jī)之類的很熟了,你可以跳過開頭,直接從 "即時(shí)編譯: PyPy和它的未來(lái)" 這部分開始看起。

Python是解釋型的還是編譯型的?

這是個(gè)Python新人都會(huì)迷惑的問題。

首先需要明了的是Python只是一個(gè)接口。有一個(gè)關(guān)于Python應(yīng)該做什么以及怎么做的具體說明(就像其他任何接口一樣 ),并且對(duì)應(yīng)的有很多具體的實(shí)現(xiàn)(也像其他接口一樣)。

其次需要知道的是“解釋型”和“編譯型”是具體實(shí)現(xiàn)的特性,而不是接口的特性。

所以,這個(gè)問題本身就沒有組織好。

Python是解釋型還是編譯型的?這個(gè)問題真的沒有組織好。

對(duì)使用最廣泛的實(shí)現(xiàn)(CPython:用C實(shí)現(xiàn)的,通常簡(jiǎn)單的說成Python,若你不知道我所說的這些,那很肯能你在使用的就是CPython)而言,這個(gè)問題的答案是:解釋型,但帶有一些編譯型特征。CPython把Python源碼編譯*成字節(jié)碼,之后再解釋這些字節(jié)碼,執(zhí)行之。

*注意:這個(gè)編譯不是通常意義上的編譯。通常我們說的編譯,是指把高級(jí)語(yǔ)言代碼轉(zhuǎn)換成機(jī)器碼。但這里的編譯實(shí)際上是另一種意義上的編譯。(譯者,這句話不是很懂,原文是it is a ‘compilation’ of sorts,不知作何解,求教各位讀者。)

再詳細(xì)看下上面的答案吧,這有助于我們理解本文中后面會(huì)講到的幾個(gè)概念。

字節(jié)碼 vs. 機(jī)器碼

了解字節(jié)碼和機(jī)器碼(或者native code)的區(qū)別是很重要的,最好的辦法或許是看看例子:

C代碼被編譯成機(jī)器碼,將在處理器上直接執(zhí)行。每一條指令控制CPU工作。
Java代碼被編譯成字節(jié)碼,將在Java虛擬機(jī)(JVM)這個(gè)抽象的計(jì)算機(jī)上執(zhí)行。每一條指令由JVM處理,JVM同計(jì)算機(jī)本身之間交互。
簡(jiǎn)而言之:機(jī)器碼快的多,但字節(jié)碼更易遷移,也更安全。

機(jī)器碼隨機(jī)器的變化而變化,但字節(jié)碼在所有的機(jī)器上都是一樣的。有人可能會(huì)認(rèn)為機(jī)器碼是對(duì)特定環(huán)境優(yōu)化了的。

回到CPython,工具鏈的執(zhí)行過程如下:
CPython編譯你的Python源代碼,生成字節(jié)碼。
字節(jié)碼隨后在CPython虛擬機(jī)上執(zhí)行。

初學(xué)者常常因?yàn)榭吹?pyc文件而假設(shè)Python是編譯型的。這也有一些合理性:.pyc文件正式之后要解釋的字節(jié)碼文件。所以,你若之前運(yùn)行過你的Python代碼,生成了.pyc文件,再次運(yùn)行時(shí)就要快得多,因?yàn)椴恍枰俅尉幾g生成字節(jié)碼了。

可選的虛擬機(jī):Jython,IronPython等

正如我之前所述,Python有很多實(shí)現(xiàn)。前面也提到,CPython是最通用的。這是一個(gè)用C實(shí)現(xiàn)的,被認(rèn)為是”默認(rèn)“的實(shí)現(xiàn)。

但其他的呢?其中最顯赫的之一就是Jython,一個(gè)用Java實(shí)現(xiàn)的采用了JVM的實(shí)現(xiàn)。CPython生成在CPython虛擬機(jī)上運(yùn)行的字節(jié)碼,而Jython生成在JVM上運(yùn)行的java字節(jié)碼(這同編譯Java程序生成java字節(jié)碼的過程是一樣的)。

困擾多年的問題,Python到底是語(yǔ)言,還是工具,哈佛教授完美詮釋
”為啥你要用其他的實(shí)現(xiàn)?”,你可能會(huì)如此發(fā)問。好吧,對(duì)開發(fā)者而言,不同的實(shí)現(xiàn)對(duì)不同的技術(shù)難題的支持程度不一樣。

CPython中很容易為你的Python代碼寫C擴(kuò)展,因?yàn)樽罱K都是由C解釋器執(zhí)行的。另一方面,Jython則使得和其他java程序共同工作很容易:無(wú)需其他工作,你就可導(dǎo)入任何Java類,在你的Jython程序中使用其他Java類。(題外話,若你沒有認(rèn)真思考,這一段會(huì)很難。此時(shí)我們已經(jīng)在討論把不同語(yǔ)言的代碼混在一起,并編譯成同一程序。(Rostin 提出混合Fortran和C代碼編程已經(jīng)有一段時(shí)間了。所以,這并不新鮮,但仍然很酷。))

下面是一個(gè)例子,一段合法的Jython代碼:

[Java HotSpot(TM) 64-Bit Server VM (Apple Inc.)] on java1.6.0_51

from java.util import HashSet

s = HashSet(5)

s.add("Foo")

s.add("Bar")

s

[Foo, Bar]

IronPython是另一很流行的Python 實(shí)現(xiàn),完全用C#實(shí)現(xiàn),針對(duì).NET平臺(tái)。她運(yùn)行在可以叫做.NET虛擬機(jī)的平臺(tái)上,這是微軟的 Common Language Runtime (CLR),同JVM相對(duì)應(yīng)。

你可能會(huì)說,Jython:Java::IronPython:C#。它們各自運(yùn)行在相同的虛擬機(jī)上,你能從你的IronPython中導(dǎo)入C#的類,從你寫的Jython代碼中帶入Java類,等等

你完全可以不用任何非CPython的實(shí)現(xiàn)就能完成你手上的任何工作。但是使用這些技術(shù)也是有很多的好處的,大部分取決于你現(xiàn)在所使用的技術(shù)棧。 你使用了很多基于JVM的語(yǔ)言?Jython就是為你準(zhǔn)備的。使用的都是.NET世界的語(yǔ)言?那么你應(yīng)該試試IronPython了(或許你已經(jīng)在用了)

困擾多年的問題,Python到底是語(yǔ)言,還是工具,哈佛教授完美詮釋
順便說一下(盡管這不是使用不同的實(shí)現(xiàn)的理由),注意Python的各種實(shí)現(xiàn)在對(duì)待你的Python源碼的時(shí)候所做的處理方式是完全不一樣的。然后這些差異是很小的,由于這些實(shí)現(xiàn)都在不停的發(fā)展改進(jìn)中,隨著時(shí)間的推移,這些差異會(huì)慢慢融合和兼容。比如,IronPython默認(rèn)情況下使用Unicode字符串,但是在2.x版本的CPython中默認(rèn)是ASCII字符串(如果使用了非ASCII字符串,會(huì)拋出一個(gè)UnicodeEncodeError錯(cuò)誤),但是在3.x版本里面CPythong已經(jīng)默認(rèn)支持Unicode字符串了。

即時(shí)編譯: PyPy和它的未來(lái)

我們已經(jīng)有了一個(gè)使用C寫的Python實(shí)現(xiàn),一個(gè)用Java寫的,一個(gè)用C#寫的。接下來(lái)就是:用Python寫的Python實(shí)現(xiàn)(有心人可能會(huì)注意這句話有點(diǎn)問題,是個(gè)死循環(huán),^_^)

接下來(lái)我們看下什么地方容易搞混淆。首先,我們討論下即時(shí)編譯器JIT

JIT: 為什么會(huì)有這個(gè)?它的原理是什么?

大家都知道本地機(jī)器碼的速度比字節(jié)碼的速度快很多。那么,如果我們能將一些字節(jié)碼直接編譯成本地機(jī)器碼再去運(yùn)行它會(huì)怎樣呢?我們必須花費(fèi)一些代價(jià)(比如時(shí)間)在編譯字節(jié)碼到本地機(jī)器碼上,如果最終的運(yùn)行時(shí)間更快,那么這個(gè)代價(jià)就是值得的。這就是JIT編譯器的動(dòng)機(jī),一種混合了解釋器和編譯器好處的技術(shù)。簡(jiǎn)單來(lái)講,JIT就是想通過編譯技術(shù)提升腳本解釋器系統(tǒng)的速度

喜歡這篇文章的話,轉(zhuǎn)發(fā)+評(píng)論哦!讓大家看看你獨(dú)特的見解哦!

好了給大家送上這一篇文的福利 加我QQ群:836962007 即可獲取哦!

困擾多年的問題,Python到底是語(yǔ)言,還是工具,哈佛教授完美詮釋

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI