python基礎(8)python中is和==的區別詳解


前置知識點

當我們創建一個對象時,我們要知道它內部干了些什么

  • 1.創建了一個隨機id,開辟了一片內存地址
  • 2.自動聲明了這個對象的類型type
  • 3.給這個對象賦值value
     

小例子

a = 1
print(id(1))
print(id(a))
print(type(a))

結果

4470700832
4470700832
<class 'int'>

可以明顯看出數字1的內存地址跟對象a的內存地址是一樣的,a = 1的原理是首先內存中有一個id=4470700832type=intvalue=1的對象,然后創建a對象指向1,此時a的id、type、value跟1的一樣
 

is和==的區別

上面分析了創建對象的整個內存過程,那么接下來理解is和==的區別就好多了

  • is:用於判斷兩個變量引用對象是否為同一個,既比較對象的地址。
  • ==:用於判斷引用變量引用對象的值是否相等,默認調用對象的 __eq__()方法。
>>> a = 257
>>> b = 257
>>> id(a)
140204598140720
>>> id(b)
140204598140400
>>> print(a is b)
False
>>> print(a == b)
True

根據我們上面講解的,a的地址和b的地址應該跟257的地址相同,但是現在顯然不同,這是為什么呢?下面會說明
 

整數緩存問題

Python 僅僅對比較小的整數對象進行緩存(范圍為[-5, 256])緩存起來,而並非是所有整數對象。需要注意的是,這僅僅是在命令行中執行,而在Pycharm或者保存為文件執行,結果是不一樣 的,這是因為解釋器做了一部分優化(范圍是[-5,任意正整數])。
 

總結

  • is 比較兩個對象的 id 值是否相等,是否指向同一個內存地址
  • == 比較的是兩個對象的內容是否相等,值是否相等
  • 小整數對象[-5,256]在全局解釋器范圍內被放入緩存供重復使用
  • is 運算符比 == 效率高,在變量和 None 進行比較時,應該使用 is。
     

字符串駐留機制

 

什么是字符串駐留?

字符串駐留是一種僅保存一份相同且不可變字符串的方法。

基本原理
系統維護interned字典,記錄已被駐留的字符串對象。
當字符串對象a需要駐留時,先在interned檢測是否存在,若存在則指向存在的字符串對象,a的引用計數減1;
若不存在,則記錄a到interned
 

為什么要字符串駐留?

  • 顯而易見,節省大量內存
  • 在字符串比較時,非駐留比較效率o(n),駐留時比較效率o(1)。

     

字符串什么時候駐留?

1.字符串只在編譯時進行駐留,而非運行時。

>>> a = "hello" + "world"
>>> a is "helloworld"
True
>>> a = "hello"
>>> b = "world"
>>> a + b is "helloworld"
False

 

2. 字符串長度為0和1時,默認都采用了駐留機制。

>>> a = "*"
>>> b = "*"
>>> a is b
True
>>> a = "**"
>>> b = "**"
>>> a is b
False

 

3. 字符串>1時,且只含大小寫字母、數字、下划線時,才會默認駐留。

>>> a = "hello1_"
>>> b = "hello1_"
>>> a is b
True
>>> a = "hello!"
>>> b = "hello!"
>>> a is b
False

 

4. 用乘法得到的字符串,有以下2種情況。

  • a. 乘數為1時,詳見Python代碼:
# 乘數=1,僅含大小寫字母、數字、下划線駐留
>>> a = "abcdefghijklmnopqrstuvwxyz1234567890_ABCDXYZ"
>>> b = a * 1
>>> a is b
True

# 乘數=1,含其他字符,長度≤1,默認駐留
>>> a = "#"
>>> b = "#" * 1
>>> a is b
True

# 乘數=1,含其他字符,長度>1,則不駐留
>>> a = "##"
>>> b = "##" * 1
>>> a is b
False
  • b.乘數>=2時,詳見Python代碼:
## 僅含有大小寫字母、數字、下划線,默認駐留
>>> a = "hellohellohellohellohellohellohello"
>>> b = "hello"*7
>>> a is b
True

# 含其他字符串,默認不駐留
>>> a = "&&&&"
>>> b = "&"*4
>>> a is b
False

 

5. 字符串被sys.intern() 指定駐留。

>>> from sys import intern
>>> a = intern("hello#!")
>>> b = intern("hello#!")
>>> a is b
True
>>> 

最后,當不滿足標識符規則時,則不會啟用駐留機制,當然這只出現在命令行中,如果你使用pycharm則不會出現這樣的情況,pycharm內部已經幫我們做了處理


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM