国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學(xué)院 > 開發(fā)設(shè)計(jì) > 正文

解釋型語言和編譯型語言的不同以及Python如何運(yùn)行

2019-11-14 17:03:10
字體:
供稿:網(wǎng)友

計(jì)劃寫關(guān)于Python中如何實(shí)現(xiàn)屬性管理、函數(shù)(或類方法)管理、類管理的幾篇成系列的文章。
而這篇文章寫在這個(gè)系列之前,希望對(duì)后面幾篇文章的理解有所幫助。
老實(shí)說,我也是在網(wǎng)上搜索了一些資料才寫的這篇文章,如果有的地方寫的不夠好,請(qǐng)指正...

何為編譯?

  1. 生成目標(biāo)文件。
  2. 且目標(biāo)文件是針對(duì)特定的 CPU 體系的(注意,開頭用了"且"字)。
    為ARM生成的目標(biāo)文件,不能被用于MipS的CPU,也不能用于x86的CPU。反過來說也是成立的。
    也就是說這段代碼在生成目標(biāo)文件的過錯(cuò)中就已經(jīng)被翻譯成了目標(biāo)CPU指令,所以如果這個(gè)程序需要在另外一種CPU上面運(yùn)行,這個(gè)代碼就必須重新翻譯。
    而上述這個(gè)翻譯過程叫做編譯。

何為解釋?

對(duì)于各種非編譯型語言(例如python/java)來說,可能不存在某種翻譯成中間文件的過錯(cuò),可能存在某種編譯成中間文件的過程
如果存在翻譯過錯(cuò),那么他們翻譯生成的通常是一種『平臺(tái)無關(guān)』的中間代碼,這種代碼一般不是針對(duì)特定的CPU平臺(tái),他們是在運(yùn)行過程中才被翻譯成目標(biāo)CPU指令的,因而在ARM CPU上能執(zhí)行,換到MIPS也能執(zhí)行,換到x86也能執(zhí)行,不需要重新對(duì)源代碼進(jìn)行翻譯。
而由于這些中間代碼并不是能在CPU上直接運(yùn)行,所以需要某種中介(叫做虛擬機(jī))在執(zhí)行時(shí)負(fù)責(zé)把代碼翻譯成CPU能執(zhí)行的指令。

區(qū)別

編譯型語言生成的文件已經(jīng)針對(duì)某個(gè)特定的CPU生成了最終文件,所以在下載的時(shí)候針對(duì)不同的CPU下載不同的文件,這就是為什么在網(wǎng)上下載某個(gè)文件時(shí),Windows系統(tǒng)用戶下載Windows的下載包(因?yàn)閃indows是操作x86系列CPU的),而Android手機(jī)(因?yàn)锳ndroid是操作ARM系列CPU的)需要下載Android類型的下載包。
針對(duì)解釋型語言,因?yàn)槟愕闹虚g文件并不是針對(duì)某個(gè)CPU的,所以如果某人在網(wǎng)上共享了一個(gè)Python源代碼或者中間代碼(字節(jié)碼),那么不管你運(yùn)行什么操作系統(tǒng),下載的文件是一樣的。而如果你原來沒有下載虛擬機(jī)的話,可能你需要下載一個(gè)虛擬機(jī)才能夠運(yùn)行這個(gè)下載的文件。
你可能會(huì)說,我只要裝了Python,就可以運(yùn)行下載下來的Python文件了呀,這是因?yàn)槟阆螺d的Python運(yùn)行包中已經(jīng)包含了一個(gè)虛擬機(jī)。

簡單總結(jié):

1,編譯型語言在編譯過程中生成目標(biāo)平臺(tái)的指令,解釋型語言在運(yùn)行過程中才生成目標(biāo)平臺(tái)的指令。
2,虛擬機(jī)的任務(wù)是在運(yùn)行過程中將中間代碼翻譯成目標(biāo)平臺(tái)的指令。

優(yōu)缺點(diǎn)

  1. 解釋語言需要考慮不同平臺(tái)的共性。比如A平臺(tái)支持加法和乘法,而B平臺(tái)僅支持加法。為了執(zhí)行9乘9這個(gè)操作同時(shí)還要保證它在A和B兩個(gè)平臺(tái)上都能運(yùn)行,必須將9乘9翻譯成A.B兩平臺(tái)都支持的加法,即9個(gè)9相加。所以勢(shì)必會(huì)影響效率。
  2. 解釋語言具有跨平臺(tái)的優(yōu)點(diǎn),只要在平臺(tái)上裝了針對(duì)于該平臺(tái)的虛擬機(jī),那么一次編寫,N次運(yùn)行,所以生產(chǎn)效率高。
  3. 當(dāng)代碼發(fā)生更改時(shí),解釋語言由于時(shí)解釋一句執(zhí)行一句,效率不會(huì)發(fā)生更改。但是編譯語言需要重新編譯,效率會(huì)受到影響。
  4. 對(duì)解釋型語言來說,代碼的錯(cuò)誤檢查發(fā)生在執(zhí)行時(shí)。

Python的運(yùn)作模式

講了這么多,下面的部分是才是真正對(duì)我們編寫代碼有實(shí)際影響的。

python運(yùn)行時(shí)分為下面的四步:

  • 詞法分析
  • 句法分析
  • 編譯
  • 解釋
  1. 詞法分析的工作就是將輸入的原始代碼分解為一些符號(hào)token(包括標(biāo)示符,關(guān)鍵字,數(shù)字, 操作符等)。這個(gè)過程中是不會(huì)報(bào)任何錯(cuò)的。
  2. 句法分析程序再接收這些符號(hào),并用一種結(jié)構(gòu)來展現(xiàn)它們之間的關(guān)系(在這種情況下使用的抽象語法樹)。此時(shí)如果出現(xiàn)句法錯(cuò)誤,會(huì)有提示。
    我們常說,Python運(yùn)行時(shí)不會(huì)執(zhí)行函數(shù),所以也不會(huì)報(bào)函數(shù)中的錯(cuò)誤。
    其實(shí)是說的片面的,請(qǐng)看下面的代碼,我在函數(shù)f中寫了一個(gè)語法錯(cuò)誤,Python會(huì)報(bào)錯(cuò)。

    L=[1,2,3]def f():    L1=[for i in L]

    執(zhí)行結(jié)果如下:

      File "hh.py", line 4    L1=[for i in L]          ^SyntaxError: invalid syntax
  3. 在句法分析后Python接收這棵抽象語法樹,并將它轉(zhuǎn)化為一個(gè)(或多個(gè))代碼對(duì)象。此時(shí)會(huì)出現(xiàn)我們說的中間碼,或者說字節(jié)碼。

    >>> def f(x=1,y=2):...   a='a'...   b='b'...   return x+y... >>> f.__code__<code object f at 0x7fe93cdfc5d0, file "<stdin>", line 1>>>> dir(f.__code__)['__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__rePR__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'co_argcount', 'co_cellvars', 'co_code', 'co_consts', 'co_filename', 'co_firstlineno', 'co_flags', 'co_freevars', 'co_kwonlyargcount', 'co_lnotab', 'co_name', 'co_names', 'co_nlocals', 'co_stacksize', 'co_varnames']>>> f.__code__.co_name'f'>>> f.__code__.co_nlocals   #定義的局部變量個(gè)數(shù)4>>> f.__code__.co_varnames('x', 'y', 'a', 'b')>>> f.__code__.co_argcount  2>>> f.__code__.co_code      #字節(jié)碼b'd/x01/x00}/x02/x00d/x02/x00}/x03/x00|/x00/x00|/x01/x00/x17S'

    如果我們直接運(yùn)行一個(gè)Python文件,那么Python在執(zhí)行完后就把這個(gè)字節(jié)碼文件刪除掉了,因?yàn)镻ython認(rèn)為復(fù)用性不高。
    但是如果是一個(gè)模塊文件,那么Python會(huì)存起來,我們來做個(gè)實(shí)驗(yàn)。
    a.py

    import b

    b.py

    def f(a=1):    print(a)

    當(dāng)我們運(yùn)行只有唯一一條語句的a.py時(shí),Python會(huì)創(chuàng)立一個(gè)__pycache__的文件夾,其中就包括了b.cpython-34.pyc文件,這個(gè)就是b.py的字節(jié)碼文件,如果用open函數(shù)打開來看看,就會(huì)看到下面的二進(jìn)制文件,如果用普通方式打開,那么會(huì)提示編碼錯(cuò)誤。

    >>> open('__pycache__/b.cpython-34.pyc','rb').read()b'/xee/x0c/r/n0%/xd8U/x19/x00/x00/x00/xe3/x00/x00/x00/x00/x00/x00/x00/x00/x00/x00/x00/x00/x03/x00/x00/x00@/x00/x00/x00s/x13/x00/x00/x00d/x00/x00d/x01/x00d/x02/x00/x84/x01/x00Z/x00/x00d/x03/x00S)/x04/xe9/x01/x00/x00/x00c/x01/x00/x00/x00/x00/x00/x00/x00/x01/x00/x00/x00/x02/x00/x00/x00C/x00/x00/x00s/x0e/x00/x00/x00t/x00/x00|/x00/x00/x83/x01/x00/x01d/x00/x00S)/x01N)/x01/xda/x05print)/x01/xda/x01a/xa9/x00r/x04/x00/x00/x00/xfa/x13/home/aaa/proj/b.py/xda/x01f/x01/x00/x00/x00s/x02/x00/x00/x00/x00/x01r/x06/x00/x00/x00N)/x01r/x06/x00/x00/x00r/x04/x00/x00/x00r/x04/x00/x00/x00r/x04/x00/x00/x00r/x05/x00/x00/x00/xda/x08<module>/x01/x00/x00/x00s/x00/x00/x00/x00'
  4. 解釋器逐個(gè)接收這些代碼對(duì)象,并執(zhí)行它們所代表的代碼。

題外話

以下題外話摘錄于網(wǎng)上,如果有什么地方不對(duì),請(qǐng)指正。
現(xiàn)在關(guān)于解釋和編譯的界限也不是特別清晰了。
Java需要預(yù)先把代碼編譯成虛擬機(jī)指令的,然后在運(yùn)行這些虛擬機(jī)指令,有的教科書上會(huì)成為混合型或者半編譯型。
像Python和lua這樣就更不好分了,可以直接解釋源代碼運(yùn)行,也可以編譯為虛擬機(jī)指令然后再運(yùn)行。
php編譯之后的結(jié)果可以被Web Server緩存起來,甚至還可以先被翻譯為C++,然后再編譯。
.NET 的CLR運(yùn)行時(shí)是Windows的組成部分,編譯好的.NET 系列語言的代碼直接生成可執(zhí)行文件,然后被“直接”執(zhí)行,看起來跟C沒有什么太大的差別。
Javascript可以被V8引擎編譯為機(jī)器碼然后執(zhí)行,如果在node.js下,這個(gè)編譯結(jié)果被緩存起來了,你說這跟編譯好再執(zhí)行的C有什么區(qū)別?

編譯型語言

1、編輯:用編輯軟件(EDIT.EXE或記事本)形成源程序(.ASM),如:LX.ASM;
2、匯編:用匯編程序(MASM.EXE)對(duì)源程序進(jìn)行匯編,形成目標(biāo)文件(.OBJ),格式如下:MASM LX.ASM;
3、連接:用連接程序(LINK.EXE)對(duì)目標(biāo)程序進(jìn)行連接,形成可執(zhí)行文件(.EXE),格式如下:LINK LX.OBJ;
4、執(zhí)行:如果結(jié)果在屏幕在顯示,則直接執(zhí)行可執(zhí)行文件。
5、調(diào)試:用調(diào)試程序(DEBUG.EXE)對(duì)可執(zhí)行文件進(jìn)行調(diào)試,格式如下:DEBUG LX.EXE
目標(biāo)代碼由機(jī)器指令組成,一般不能獨(dú)立運(yùn)行,因?yàn)樵闯绦蛑锌赡苁褂昧四承﹨R編程序不能解釋引用的庫函數(shù),而庫函數(shù)代碼又不在源程序中,此時(shí)還需要鏈接程序完成外部引用和目標(biāo)模塊調(diào)用的鏈接任務(wù),最后輸出可執(zhí)行代碼

如果對(duì)這個(gè)方向很感興趣,那么下面的幾篇文章可以進(jìn)一步閱讀:
http://python.jobbole.com/81660/
http://developer.51cto.com/art/201309/410862.htm
http://developer.51cto.com/art/201003/190924.htm


發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 河南省| 周至县| 会泽县| 惠州市| 鄂尔多斯市| 西和县| 崇仁县| 西乌珠穆沁旗| 伊吾县| 珲春市| 错那县| 射洪县| 宿迁市| 蚌埠市| 寿宁县| 兴国县| 濮阳市| 蒙城县| 长沙县| 株洲市| 涿州市| 怀安县| 临猗县| 左贡县| 宜州市| 肇东市| 万荣县| 太湖县| 泌阳县| 花莲市| 安达市| 通河县| 谷城县| 临泽县| 肥西县| 高阳县| 京山县| 呼图壁县| 松阳县| 崇阳县| 邢台市|