91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

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

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

當使用print時Python是如何運行的

發布時間:2022-02-22 16:43:03 來源:億速云 閱讀:159 作者:iii 欄目:開發技術

這篇“當使用print時Python是如何運行的”文章的知識點大部分人都不太理解,所以小編給大家總結了以下內容,內容詳細,步驟清晰,具有一定的借鑒價值,希望大家閱讀完這篇文章能有所收獲,下面我們一起來看看這篇“當使用print時Python是如何運行的”文章吧。

眾所周知,Python 是一門解釋型的語言

——所謂“解釋型”,當然是區別于以 C語言 為代表的編譯型語言。編譯型語言需要將整個程序文件全部轉換為可以直接由機器執行的二進制文件;而解釋型語言則是由相應的解釋器一行一行“解釋”并執行代碼描述的行為。

正是因此,對于新接觸的人來說,Python這樣的解釋性語言很多時候需要執行到相應的語句,才會發現一些顯然的錯誤。

話說回來,Python的解釋器是怎么樣來“解釋”Python代碼的呢?

實際上,類似于Java的執行機制,Python也擁有自己的虛擬機。而這個虛擬機實際上執行的也是一種“字節碼”。

Python程序的執行中依然存在一個“編譯”的過程:將Python代碼編譯為字節碼。

并且,Python也提供了一個名為dis模塊,用于查看、分析Python的字節碼。

1. dis模塊

舉例來說,dis模塊中有一個同名函數dis,可以用于將當前命名空間中的對象反匯編為字節碼。

import dis


def add(add_1, add_2):
    sum_value = add_1 + add_2


dis.dis(add)

執行結果為:

  4           0 LOAD_FAST                0 (add_1)
              2 LOAD_FAST                1 (add_2)
              4 BINARY_ADD
              6 STORE_FAST               2 (sum_value)
              8 LOAD_CONST               0 (None)
             10 RETURN_VALUE

其中,開頭的數字“4”表示字節碼的內容對應于腳本中第 4 行的內容。

隨后的一列數字則表示對應指令所在的地址。縱向觀察可以發現一個規律:下一條指令的地址總比上一條指令的地址大 2 。這是巧合嗎?

顯然不是的。官方文檔《dis --- Python 字節碼反匯編器》中記錄的更改顯示,從Python 3.6版本開始,”每條指令使用2個字節“。所以每條指令的地址會在上一條指令地址的基礎上加2。

再往后,是一列表示指令含義的單詞組合,實際上就是人類可讀的對應指令名稱。顧名思義,LOAD_FAST就是加載某個內容/對象到某處,”FAST“很可能意味著這是一個便捷快速的命令實現。

最右邊,則是對應于當前命令的操作數,即操作對象。數字同樣是一個類似于地址的表示,括號中的字符串則表示相應對象在Python代碼中的具體名稱。

這樣我們就可以大概地閱讀生成的字節碼了:

首先Python將函數add的第一個參數add_1加載到某處,緊跟著將第二個參數add_2加載到第一個參數之后。然后調用了一個名為BINARY_ADD的指令,即對之前加載的兩個參數做加法。再然后則是將加法所得的和sum_value存儲在了另一個位置。最后,加載了一個常量None并返回。

其實讀完上面這個執行過程,我們很容易想到一種常用的數據結構——棧。

當然這并不是本文的重點——真要探討Python的實現機制,還得另外寫幾篇長文才能說得一二。

使用dis.dis函數除了可以查看當前腳本中各個對象對應的字節碼,還可以直接傳入一段代碼對應的字符串進行反匯編:

# test_dis.py
import dis




s = """
def add(add_1, add_2):
    sum_value = add_1 + add_2


print("Hello World!")


import sys
"""


dis.dis(s)

匯編結果:

  2           0 LOAD_CONST               0 (<code object add at 0x0000019FF66DFDB0, file "<dis>", line 2>)
              2 LOAD_CONST               1 ('add')
              4 MAKE_FUNCTION            0
              6 STORE_NAME               0 (add)


  5           8 LOAD_NAME                1 (print)
             10 LOAD_CONST               2 ('Hello World!')
             12 CALL_FUNCTION            1
             14 POP_TOP


  7          16 LOAD_CONST               3 (0)
             18 LOAD_CONST               4 (None)
             20 IMPORT_NAME              2 (sys)
             22 STORE_NAME               2 (sys)
             24 LOAD_CONST               4 (None)
             26 RETURN_VALUE

2. compile函數

除了在程序中直接給出要反匯編的程序形成的字符串,我們還可以通過使用內置函數compile來形成相應腳本的編譯對象,再使用dis.dis查看其字節碼內容。

# test_compile.py
import dis


with open("test_dis.py", "r", encoding="utf-8") as f:
    s = f.read()


compile_obj = compile(s, "test_dis.py","exec")


dis.dis(compile_obj)

字節碼輸出結果:

  1           0 LOAD_CONST               0 (0)
              2 LOAD_CONST               1 (None)
              4 IMPORT_NAME              0 (dis)
              6 STORE_NAME               0 (dis)


 11           8 LOAD_CONST               2 ('\ndef add(add_1, add_2):\n    sum_value = add_1 + add_2\n\nprint("Hello World!")\n\nimport sys\n')
             10 STORE_NAME               1 (s)


 13          12 LOAD_NAME                0 (dis)
             14 LOAD_METHOD              0 (dis)
             16 LOAD_NAME                1 (s)
             18 CALL_METHOD              1
             20 POP_TOP
             22 LOAD_CONST               1 (None)
             24 RETURN_VALUE

以上就是關于“當使用print時Python是如何運行的”這篇文章的內容,相信大家都有了一定的了解,希望小編分享的內容對大家有幫助,若想了解更多相關的知識內容,請關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

洪湖市| 舟山市| 延长县| 工布江达县| 和平县| 双柏县| 铜川市| 井陉县| 桦甸市| 手游| 满城县| 永靖县| 桓仁| 大冶市| 崇仁县| 徐水县| 花垣县| 额尔古纳市| 广灵县| 平度市| 日土县| 秭归县| 炉霍县| 阿拉善右旗| 揭东县| 娱乐| 青浦区| 县级市| 邢台县| 独山县| 苗栗县| 涿州市| 多伦县| 盱眙县| 石林| 读书| 什邡市| 南丰县| 嫩江县| 鲜城| 临沭县|