python直譯器哪一年 Python直譯器簡介

2021-10-10 19:28:49 字數 2140 閱讀 8755

python直譯器簡介

函式物件

>>> def foo(a):

... x = 3

... return x + a

>>> foo

python中的函式是乙個物件

**物件

函式的func_code屬性就是**物件

>>> def foo(a):

... x = 3

... return x + a

>>> foo

>>> foo.func_code

", line 1>

我們只關注3個有趣的 foo 函式**物件的屬性。

>>> foo.func_code.co_varnames

('a', 'x')

>>> foo.func_code.co_consts

(none, 3)

>>> foo.func_code.co_argcount

通過呼叫它們,我們能依次得到:變數名、函式中已知的常量和函式引數的數量。但是目前為止,我們還是不知道生成**物件的指令到底是什麼。事實上,這個指令叫做位元組碼。位元組碼也是**物件的乙個屬性:

>>> foo.func_code.co_code

'd\x01\x00}\x01\x00|\x01\x00|\x00\x00\x17s'

位元組碼那麼什麼是位元組碼呢?其實,它就是一系列的位元組。這些位元組列印出來的樣子很奇怪是因為有些位元組是能夠列印的而有些不能。從分析ord的每個位元組中我們看到它們只是數字而已。

>>> [ord(b) for b in foo.func_code.co_code]

[100, 1, 0, 125, 1, 0, 124, 1, 0, 124, 0, 0, 23, 83]

這就是那些組成python位元組碼的位元組。直譯器會迴圈接收各個位元組,查詢每個位元組的指令然後執行這個指令。需要注意的是,位元組碼本身並不包括任何python物件,或引用任何物件。

如果你想知道python位元組碼的意思,可以去找到cpython直譯器檔案(ceval.c),然後查閱100的意思、1的意思、0的意思,等等。在後續內容中,我們會這麼做的!但暫時可以用更簡單的方法: dis 模組。

反彙編位元組碼

反彙編位元組碼的意思就是接收這一系列的位元組,然後列印出我們能夠理解的字元。這並不是python的工作; dis模組只是幫助我們了解python內部工作的中間狀態。我不支援在產品**中使用 dis ——它是面向程式設計師的,不是電腦。

但是,現在我們需要做的正是讓一些位元組碼變得更通俗易懂,所以 dis 是乙個非常理想的工具。我們將使用 dis.dis 函式去分析 foo 函式的**物件。

>>> def foo(a):

... x = 3

... return x + a

>>> import dis

>>> dis.dis(foo.func_code)

2 0 load_const 1 (3)

3 store_fast 1 (x)

3 6 load_fast 1 (x)

9 load_fast 0 (a)

12 binary_add

13 return_value

(你通常會看到這種寫法:dis.dis(foo),直接分析它的函式物件。這其實是一種簡便寫法: dis 真正分析的還是**物件。如果要傳遞乙個函式,那麼只能接收到它的**物件。)

左邊那一列數字是原始源**的行號。第二列是位元組碼的偏移量:load_const在第0行,store_fast在第3行,以此類推。中間那列是位元組的名字。它們是為程式設計師所準備的——直譯器是完全不需要的。

最後兩列告訴我們一些關於指令引數(如果有的話)的細節。第四列是引數本身。它表示乙個指向**物件其它屬性的索引。在這個例子中,load_const的引數指向列表co_consts,store_fast的引數指向co_varnames。dis在第四列所指向的的地方查詢常數或者名稱, 最後在第五列返回給我們它找到的資料。這很容易就能得到證實了:

>>> foo.func_code.co_consts[1]

>>> foo.func_code.co_varnames[1]

'x'這也能解釋為什麼第二個指令store_fast位於位元組碼的第三行。如果乙個位元組碼有引數的話,那麼它相鄰的兩個位元組的引數和它相同。當然,正確的處理這些資料是直譯器的工作。

未完學習資料

利用Python如何輸出某一年的日曆?

利用自定而下的思想,將問題進行一步一步的分解,最後可解決問題 def getyear print this program prints the calendar of a given year.year int input please enter a year after 1900 return...

python獲取一年所有的日期

python獲取一年所有的日期 自動識別閏年。import arrow def isleapyear years 通過判斷閏年,獲取年份years下一年的總天數 param years 年份,int return days sum,一年的總天數 斷言 年份不為整數時,丟擲異常。assert isin...

一年級加減法出題器

給小學僧一年級做的乙個加減法出題器,要求是兩個數加減,其中乙個數為一位數,且結果不能為負。可打包為exe from random import randint,shuffle lst x int input 請輸入多少以內 y int input 請輸入題目數量 while true a randi...