卷2:第19章 PyPy

2018-02-24 15:55 更新

PyPy

PyPy是一個(gè)Python實(shí)現(xiàn)的動(dòng)態(tài)語(yǔ)言實(shí)現(xiàn)框架。

本章假定讀者熟悉如字節(jié)碼和常量疊算等有關(guān)解釋器和編譯器的基本概念。

19.1. 一點(diǎn)歷史

Python是一種高層次動(dòng)態(tài)編程語(yǔ)言。它是由荷蘭程序員Guido van Rossum在20世紀(jì)80年代末發(fā)明的。Guido最初的實(shí)現(xiàn)是一個(gè)用C語(yǔ)言編寫(xiě)的傳統(tǒng)的字節(jié)解釋器,人稱(chēng)CPython?,F(xiàn)在有許多其他的Python實(shí)現(xiàn)。其中最引人注目的有用Java編寫(xiě)的并允許Java代碼接口的Jython,用C#編寫(xiě)并允許和微軟.NET框架接口的IronPython,以及本章的主題PyPy。 CPython的仍然是使用最廣泛的實(shí)現(xiàn),也是當(dāng)前唯一支持下一代Python 3語(yǔ)言的實(shí)現(xiàn)。本章將談?wù)勛孭yPy與其他Python實(shí)現(xiàn)乃至其他任何動(dòng)態(tài)語(yǔ)言實(shí)現(xiàn)都有所不同的一些設(shè)計(jì)決策。

19.2. PyPy概覽

除了微不足道的少量C代碼,PyPy完全是用Python寫(xiě)成的。PyPy代碼樹(shù)包含兩個(gè)主要部分:Python解釋器和RPython翻譯工具鏈。 Python解釋器是面向程序員的運(yùn)行庫(kù),人們使用PyPy來(lái)調(diào)用Python實(shí)現(xiàn)。它實(shí)際上是用Python的一個(gè)子集——限制Python(通??s寫(xiě)為RPython)寫(xiě)成的。用RPython編寫(xiě)Python解釋器的目的是讓解釋器可以輸出給PyPy的另一個(gè)重要組成部分——RPython翻譯工具鏈。 RPython翻譯器會(huì)把RPython代碼轉(zhuǎn)換為一個(gè)選定的低級(jí)語(yǔ)言,最常用的是C。這使得PyPy成為一個(gè)自我托管的實(shí)現(xiàn),也就是說(shuō)它是用它自己實(shí)現(xiàn)的語(yǔ)言寫(xiě)成的。我們?cè)诒菊潞笪闹羞€會(huì)看到,RPython翻譯也讓PyPy成為一個(gè)普適的動(dòng)態(tài)語(yǔ)言實(shí)現(xiàn)框架。

PyPy強(qiáng)大的抽象使之成為最靈活的Python實(shí)現(xiàn)。從不同的垃圾回收到各種翻譯優(yōu)化參數(shù),它有近200個(gè)不同的配置選項(xiàng)。

19.3. Python解釋器

由于RPython是Python的真子集,PyPy Python解釋器可以不經(jīng)翻譯地在另一個(gè)Python實(shí)現(xiàn)上運(yùn)行。當(dāng)然,這會(huì)非常慢,但這樣我們就可以快速測(cè)試解釋器的變化。這也讓我們可以使用普通的Python調(diào)試工具來(lái)調(diào)試解釋其。 PyPy的解釋器的大多數(shù)測(cè)試可以同時(shí)運(yùn)行在無(wú)翻譯和有翻譯的解釋器上。這讓開(kāi)發(fā)時(shí)的快速測(cè)試成為可能,并保證了有翻譯和無(wú)翻譯的解釋器的行為一致。

在大多數(shù)情況下,PyPy Python解釋器的細(xì)節(jié)和CPython非常類(lèi)似,PyPy和CPython在解釋時(shí)使用的字節(jié)碼和數(shù)據(jù)結(jié)構(gòu)幾乎完全一樣。兩者之間的主要區(qū)別在于PyPy有一種很聰明的抽象,稱(chēng)為對(duì)象空間(簡(jiǎn)稱(chēng)objspaces)。objspace封裝了代表和操作Python數(shù)據(jù)類(lèi)型的所有知識(shí)。例如,對(duì)兩個(gè)Python對(duì)象執(zhí)行二元操作或獲取對(duì)象的一個(gè)屬性,都完全由objspace處理。這讓解釋器無(wú)需知道Python對(duì)象的任何實(shí)現(xiàn)細(xì)節(jié)。字節(jié)碼解釋器吧Python對(duì)象看成是黑盒子,并在需要操作它們時(shí)調(diào)用objspace方法。例如,下面是BINARY_ADD機(jī)器碼的一個(gè)粗糙的實(shí)現(xiàn),在兩個(gè)對(duì)象用+運(yùn)算符結(jié)合的時(shí)候會(huì)調(diào)用它。請(qǐng)注意解釋器如何不去檢查運(yùn)算符;所有處理都立即被委托給objspace。

def BINARY_ADD(space, frame):
    object1 = frame.pop() # pop left operand off stack
    object2 = frame.pop() # pop right operand off stack
    result = space.add(object1, object2) # perform operation
    frame.push(result) # record result on stack
以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)