亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Python編譯過程和執(zhí)行原理解析

 更新時(shí)間:2023年07月28日 11:22:19   作者:Token_w  
這篇文章主要介紹了Python編譯過程和執(zhí)行原理解析,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下

一. Python執(zhí)行原理

這里的解釋執(zhí)行是相對(duì)于編譯執(zhí)行而言的。我們都知道,使用C/C++之類的編譯性語言編寫的程序,是需要從源文件轉(zhuǎn)換成計(jì)算機(jī)使用的機(jī)器語言,經(jīng)過鏈接器鏈接之后形成了二進(jìn)制的可執(zhí)行文件。運(yùn)行該程序的時(shí)候,就可以把二進(jìn)制程序從硬盤載入到內(nèi)存中并運(yùn)行。

但是對(duì)于Python而言,Python源碼不需要編譯成二進(jìn)制代碼,它可以直接從源代碼運(yùn)行程序。當(dāng)我們運(yùn)行Python文件程序的時(shí)候,Python解釋器將源代碼轉(zhuǎn)換為字節(jié)碼,然后再由Python解釋器來執(zhí)行這些字節(jié)碼。這樣,Python就不用擔(dān)心程序的編譯,庫(kù)的鏈接加載等問題了。

對(duì)于Python解釋語言,有以下3方面的特性:

  • 每次運(yùn)行都要進(jìn)行轉(zhuǎn)換成字節(jié)碼,然后再有虛擬機(jī)把字節(jié)碼轉(zhuǎn)換成機(jī)器語言,最后才能在硬件上運(yùn)行。與編譯性語言相比,每次多出了編譯和鏈接的過程,性能肯定會(huì)受到影響。
  • 由于不用關(guān)心程序的編譯和庫(kù)的鏈接等問題,開發(fā)的工作也就更加輕松啦。
  • Python代碼與機(jī)器底層更遠(yuǎn)了,Python程序更加易于移植,基本上無需改動(dòng)就能在多平臺(tái)上運(yùn)行。

在具體計(jì)算機(jī)上實(shí)現(xiàn)一種語言,首先要確定的是表示該語言語義解釋的虛擬計(jì)算機(jī),一個(gè)關(guān)鍵的問題是程序執(zhí)行時(shí)的基本表示是實(shí)際計(jì)算機(jī)上的機(jī)器語言還是虛擬機(jī)的機(jī)器語言。這個(gè)問題決定了語言的實(shí)現(xiàn)。根據(jù)這個(gè)問題的回答,可以將程序設(shè)計(jì)語言劃分為兩大類:編譯型語言和解釋型語言。

  • 編譯實(shí)現(xiàn)的語言,如:C、C++、Fortran、Pascal、Ada。由編譯型語言編寫的源程序需要經(jīng)過編譯,匯編和鏈接才能輸出目標(biāo)代碼,然后由機(jī)器執(zhí)行目標(biāo)代碼。目標(biāo)代碼是有機(jī)器指令組成,不能獨(dú)立運(yùn)行,因?yàn)樵闯绦蛑锌赡苁褂昧艘恍﹨R編程序不能解釋引用的庫(kù)函數(shù),而庫(kù)函數(shù)又不在源程序中,此時(shí)還需要鏈接程序完成外部引用和目標(biāo)模板調(diào)用的鏈接任務(wù),最后才能輸出可執(zhí)行代碼。
  • 解釋型語言,解釋器不產(chǎn)生目標(biāo)機(jī)器代碼,而是產(chǎn)生中間代碼,這種中間代碼與機(jī)器代碼不同,中間代碼的解釋是由軟件支持的,不能直接使用在硬件上。該軟件解釋器通常會(huì)導(dǎo)致執(zhí)行效率較低,用解釋型語言編寫的程序是由另一個(gè)可以理解中間代碼的解釋程序執(zhí)行的。和編譯的程序不同的是,解釋程序的任務(wù)是逐一將源代碼的語句解釋成可執(zhí)行的機(jī)器指令,不需要將源程序翻譯成目標(biāo)代碼再執(zhí)行。對(duì)于解釋型語言,需要一個(gè)專門的解釋器來執(zhí)行該程序,每條語句只有在執(zhí)行是才能被翻譯,這種解釋型語言每執(zhí)行一次就翻譯一次,因而效率低下。
  • Java解釋器,java很特殊,java是需要編譯的,但是沒有直接編譯成機(jī)器語言,而是編譯成字節(jié)碼,然后在Java虛擬機(jī)上用解釋的方式執(zhí)行字節(jié)碼。Python也使用了類似的方式,先將Python編譯成Python字節(jié)碼,然后由一個(gè)專門的Python字節(jié)碼解釋器負(fù)責(zé)解釋執(zhí)行字節(jié)碼。
  • Python是一門解釋語言,但是出于效率的考慮,提供了一種編譯的方法。編譯之后就得到pyc文件,存儲(chǔ)了字節(jié)碼。Python這點(diǎn)和java很類似,但是java與Python不同的是,Python是一個(gè)解釋型的語言,所以編譯字節(jié)碼不是一個(gè)強(qiáng)制的操作,事實(shí)上,編譯是一個(gè)自動(dòng)的過程,一般不會(huì)在意它的存在。編譯成字節(jié)碼可以節(jié)省加載模塊的時(shí)間,提高效率。
  • 除了效率之外,字節(jié)碼的形式也增加了反向工程的難度,可以保護(hù)源代碼。這個(gè)只是一定程度上的保護(hù),反編譯還是可以的。

二. Python內(nèi)部執(zhí)行過程

2.1 編譯過程概述

當(dāng)我們執(zhí)行Python代碼的時(shí)候,在Python解釋器用四個(gè)過程“拆解”我們的代碼,最終被CPU執(zhí)行返回給用戶。

首先當(dāng)用戶鍵入代碼交給Python處理的時(shí)候會(huì)先進(jìn)行詞法分析,例如用戶鍵入關(guān)鍵字或者當(dāng)輸入關(guān)鍵字有誤時(shí),都會(huì)被詞法分析所觸發(fā),不正確的代碼將不會(huì)被執(zhí)行。

下一步Python會(huì)進(jìn)行語法分析,例如當(dāng)"for i in test:"中,test后面的冒號(hào)如果被寫為其他符號(hào),代碼依舊不會(huì)被執(zhí)行。

下面進(jìn)入最關(guān)鍵的過程,在執(zhí)行Python前,Python會(huì)生成.pyc文件,這個(gè)文件就是字節(jié)碼,如果我們不小心修改了字節(jié)碼,Python下次重新編譯該程序時(shí)會(huì)和其上次生成的字節(jié)碼文件進(jìn)行比較,如果不匹配則會(huì)將被修改過的字節(jié)碼文件進(jìn)行覆蓋,以確保每次編譯后字節(jié)碼的準(zhǔn)確性。

那么什么是字節(jié)碼?字節(jié)碼在Python虛擬機(jī)程序里對(duì)應(yīng)的是PyCodeObject對(duì)象。.pyc文件是字節(jié)碼在磁盤上的表現(xiàn)形式。簡(jiǎn)單來說就是在編譯代碼的過程中,首先會(huì)將代碼中的函數(shù)、類等對(duì)象分類處理,然后生成字節(jié)碼文件。有了字節(jié)碼文件,CPU可以直接識(shí)別字節(jié)碼文件進(jìn)行處理,接著Python就可執(zhí)行了。

2.2 過程圖解

在這里插入圖片描述

2.3 編譯字節(jié)碼

Python中有一個(gè)內(nèi)置函數(shù)compile(),可以將源文件編譯成codeobject,首先看這個(gè)函數(shù)的說明:

compile(...) compile(source, filename, mode[, flags[, dont_inherit]]) -> code object

參數(shù)1:源文件的內(nèi)容字符串

參數(shù)2:源文件名稱

參數(shù)3:exec-編譯module,single-編譯一個(gè)聲明,eval-編譯一個(gè)表達(dá)式 一般使用前三個(gè)參數(shù)就夠了

使用示例:

#src_file.py
#some function
def f(d=0):
    c=1
    print "hello"
a=9
b=8
f()
>>> a=open('src_file.py','r').read()    #命令行模式中打開源文件進(jìn)行編譯
>>> co=compile(a,'src_file','exec')
>>> type(co)
<type 'code'>    #編譯出了codeobject對(duì)象

2.4 codeobject對(duì)象的屬性

codeobject有哪些變量,接上節(jié)的內(nèi)容分析一下:

print(co.co_names)   #所有的符號(hào)名稱
# ('f', 'a', 'b')
print(co.co_name)#模塊名、函數(shù)名、類名
# <module>
print(co.co_consts)  #常量集合、函數(shù)f和兩個(gè)int常量a,b,d
# (0, <code object f at 0xb7273b18, file "src_file", line 2>, 9, 8, None)
print(co.co_consts[1].co_varnames)  #可以看到f函數(shù)也是一個(gè)codeobject,打印f中的局部變量
# ('c',)
print(co.co_code)  #字節(jié)碼指令
# dZdZdZedS
print(co.co_consts[1].co_firstlineno)  #代碼塊在文件中的起始行號(hào)
# 2
print(co.co_stacksize)  #代碼棧大小
# 2
print(co.co_filename)  #文件名
# src_file    #模塊名、函數(shù)名、類名 

codeobject的co_code代表了字節(jié)碼,這個(gè)字節(jié)碼有什么含義?我們可以使用dis模塊進(jìn)行Python的反編譯:

import dis
dis.dis(co)
print(output)
'''
 2        0 LOAD_CONST               0 (0)
          3 LOAD_CONST               1 (<code object f at 0xb7273b18, file "src_file", line 2>)
          6 MAKE_FUNCTION            1
          9 STORE_NAME               0 (f)
 5        12 LOAD_CONST              2 (9)
          15 STORE_NAME              1 (a)
 6        18 LOAD_CONST              3 (8)
          21 STORE_NAME              2 (b)
 7        24 LOAD_NAME               0 (f)
          27 CALL_FUNCTION           0
          30 POP_TOP             
          31 LOAD_CONST              4 (None)
          34 RETURN_VALUE '''

從反編譯的結(jié)果來看,Python字節(jié)碼其實(shí)是模仿的x86的匯編,將代碼編譯成一條一條的指令交給一個(gè)虛擬的cpu去執(zhí)行。

  • 第一列:行號(hào)
  • 第二列:指令在代碼塊中的偏移量
  • 第三列:指令
  • 第四列:操作數(shù)
  • 第五列:操作數(shù)說明

到此這篇關(guān)于Python編譯過程和執(zhí)行原理的文章就介紹到這了,更多相關(guān)Python執(zhí)行原理內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 詳解Python的Django框架中manage命令的使用與擴(kuò)展

    詳解Python的Django框架中manage命令的使用與擴(kuò)展

    這篇文章主要介紹了Python的Django框架中manage命令的使用與擴(kuò)展,manage.py使得用戶借助manage命令在命令行中能實(shí)現(xiàn)諸多簡(jiǎn)便的操作,需要的朋友可以參考下
    2016-04-04
  • 一文詳解Python中數(shù)據(jù)清洗與處理的常用方法

    一文詳解Python中數(shù)據(jù)清洗與處理的常用方法

    在數(shù)據(jù)處理與分析過程中,缺失值、重復(fù)值、異常值等問題是常見的挑戰(zhàn),本文總結(jié)了多種數(shù)據(jù)清洗與處理方法,文中的示例代碼簡(jiǎn)潔易懂,有需要的小伙伴可以參考下
    2025-01-01
  • 關(guān)于Python turtle庫(kù)使用時(shí)坐標(biāo)的確定方法

    關(guān)于Python turtle庫(kù)使用時(shí)坐標(biāo)的確定方法

    這篇文章主要介紹了關(guān)于Python turtle庫(kù)使用時(shí)坐標(biāo)的確定方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-03-03
  • 用python代碼做configure文件

    用python代碼做configure文件

    在lua中,我一直用lua作為config文件,或者承載數(shù)據(jù)的文件 - 好處是lua本身就很好閱讀,然后無需額外寫解析的代碼,還支持在configure文件中讀環(huán)境變量,條件判斷等,方便又強(qiáng)大!
    2014-07-07
  • Python編程中歸并排序算法的實(shí)現(xiàn)步驟詳解

    Python編程中歸并排序算法的實(shí)現(xiàn)步驟詳解

    這篇文章主要介紹了Python編程中歸并排序算法的實(shí)現(xiàn)步驟詳解,歸并排序的平均時(shí)間復(fù)雜度為(n\log n),需要的朋友可以參考下
    2016-05-05
  • python如何求取指定范圍內(nèi)的質(zhì)數(shù)

    python如何求取指定范圍內(nèi)的質(zhì)數(shù)

    這篇文章主要介紹了python如何求取指定范圍內(nèi)的質(zhì)數(shù)問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-08-08
  • Python3基礎(chǔ)之函數(shù)用法

    Python3基礎(chǔ)之函數(shù)用法

    這篇文章主要介紹了Python3的函數(shù)用法,非常重要,需要的朋友可以參考下
    2014-08-08
  • Python實(shí)現(xiàn)簡(jiǎn)單的ui界面的設(shè)計(jì)步驟(適合小白)

    Python實(shí)現(xiàn)簡(jiǎn)單的ui界面的設(shè)計(jì)步驟(適合小白)

    當(dāng)我們書寫一個(gè)python程序時(shí),我們?cè)诳刂婆_(tái)輸入信息時(shí),往往多有不便,并且為了更加美觀且直觀的方式輸入控制命令,我們常常設(shè)計(jì)一個(gè)ui界面,這樣就能方便執(zhí)行相關(guān)功能,如計(jì)算器、日歷等界面,本博客是為了給ui設(shè)計(jì)的小白進(jìn)行講解,需要的朋友可以參考下
    2024-07-07
  • python監(jiān)控進(jìn)程腳本

    python監(jiān)控進(jìn)程腳本

    這篇文章主要為大家詳細(xì)介紹了python監(jiān)控進(jìn)程腳本,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-04-04
  • python的pyecharts繪制各種圖表詳細(xì)(附代碼)

    python的pyecharts繪制各種圖表詳細(xì)(附代碼)

    這篇文章主要介紹了python的pyecharts繪制各種圖表詳細(xì)(附代碼),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-11-11

最新評(píng)論