1. 程式人生 > >逐行解釋和整體解釋的理解

逐行解釋和整體解釋的理解

ret 查看 -s demo 跟著 spa 函數 指定 def

首先跟著筆者的思路讀以下的代碼

片段<一>

>>> a = 10.1 >>> b = 10.1 >>> a is b False

返回false說明a和b不是指向了同一個對象,可以查看id進行判斷 >>> id(a) 140475784803760 >>> id(b) 140475784803736

片段<二>

接著看以下這一段的代碼 >>> (10.1) is (10.1) True
>>> def foo(): ... a = 10.1 ... b = 10.1 ... return a is b ... >>> foo() True
片段<三>

趣者可以嘗試著用的CPython環境裏執行下面的代碼:

def foo():
  a = 10.1
  b = 10.1
  return a is b

print(foo())

而結果總是True。

片段<四>

In [45]: def demo1():
...: return 10.2
...:

In [46]: def demo2():
...: return 10.2
...:

In [47]:

In [47]: print(demo1() is demo2())
False

In [48]:

而結果總是False。

《幫助理解文檔介紹》

背景知識

CPython的代碼的“編譯單元”是函數——每個函數單獨編譯,得到的結果是一個PyFunctionObject對象,其中帶有字節碼、常量池等各種信息。Python的頂層代碼也被看作一個函數。函數之間有嵌套時,外層函數的代碼並不包含內層函數的代碼,而只是包含創建出內層函數的函數對象(PyFunctionObject)的邏輯。(這裏的編譯單元跟之前提到過的代碼塊可以理解為同一個概念--"都是編譯時的基本單位")

在同一個編譯單元(PyFunctionObject)裏出現的值相同的常量,只會在常量池裏出現一份,一定會對應到運行時的同一個對象。所以在foo()的例子裏,a和b都從同一個常量池項獲取值;
在不同的編譯單元裏,值相同的常量不一定

會對應到運行時的同一個對象(小整數對象池 -5~256 之間的數在不同的編譯單元裏,值相同的常量會對應到同一個對象),

代碼幫助理解:

In [48]: a = 255

In [49]: def demo():
...: b = 255
...: c = 255
...: print(a is b)
...: print(b is c)
...:

In [50]: demo()
True
True

In [51]:

註:255為小整數對象池之內的數 所以 不同的編譯單元 執行的結果為true

In [51]: a = 257

In [52]: def demo():
...: b = 257
...: c = 257
...: print(a is b)
...: print(b is c)
...:

In [53]: demo()
False
True

In [54]:

註:257不是小整數對象池範圍的的數據 a和b 為兩個編譯單元所以結果為false 這裏可以觀察到 在同一個編譯單元裏 同樣的整數(b和c)只會創建一份所以返回True

“逐行解釋”?

其實在CPython的交互式解釋器(例如python命令不指定參數時)裏,每輸入一行可以立即執行的代碼,Python解釋器就會把一行當作一個編譯單元來編譯到字節碼並解釋執行;如果輸入的代碼尚未構成一個完整的單元,例如函數聲明或者類聲明,則等到獲得了完整單元的輸入後再當作一個編譯單元來處理。

所以當我們在CPython的交互式解釋器中分別輸入"a = 10.1"、"b = 10.1"這兩行時,它們分別被當作一個編譯單元處理,其中的常量池沒有共享,常量池項也都是各自新創建的,所以會得到a is b為False的結果。
而在同一環境裏輸入"(10.1) is (10.1)"時,這一行被看作一個編譯單元,其中兩次對10.1這個常量的使用都變成了對同一對象的引用,因而is的結果為True。

例:

In [57]: 10.1 is 10.1
Out[57]: True

當把 一下代碼放到同一個py文件裏去執行的時候 兩行代碼就會處於同一個編譯單元中,a is b就會是True。 同一個代碼塊(編譯單元)共享同一個常量池

a = 10.1

b = 10.1

print(a is b)

>>>True

逐行解釋和整體解釋的理解