Python基礎知識,自己寫一寫比較不容易忘
Python的每個對象都分為可變和不可變,主要的核心類型中,數字、字符串、元組是不可變的,列表、字典是可變的。
對不可變類型的變量重新賦值,實際上是重新創建一個不可變類型的對象,並將原來的變量重新指向新創建的對象(如果沒有其他變量引用原有對象的話(即引用計數為0),原有對象就會被回收)。
不可變類型以int類型為例:實際上 i += 1 並不是真的在原有的int對象上+1,而是重新創建一個value為6的int對象,i引用自這個新的對象。
>>> i = 5
>>> i += 1
>>> i
6
通過id函數查看變量i的內存地址進行驗證(使用hex(id(i)) 可以查看16進制的內存地址)
>>> i = 5 >>> i += 1 >>> i 6 >>> id(i) 140243713967984 >>> i += 1 >>> i 7 >>> id(i) 140243713967960
可以看到執行 i += 1 時,內存地址都會變化,因為int 類型是不可變的。
再改改代碼,但多個int類型的變量值相同時,看看它們內存地址是否相同。
>>> i = 5 >>> j = 5 >>> id(i) 140656970352216 >>> id(j) 140656970352216 >>> k = 5 >>> id(k) 140656970352216 >>> x = 6 >>> id(x) 140656970352192 >>> y = 6 >>> id(y) 140656970352192 >>> z = 6 >>> id(z) 140656970352192
對於不可變類型int,無論創建多少個不可變類型,只要值相同,都指向同個內存地址。同樣情況的還有比較短的字符串。
對於其他類型則不同,以浮點類型為例,從代碼運行結果可以看出它是個不可變類型:對i的值進行修改后,指向新的內存地址。
>>> i = 1.5 >>> id(i) 140675668569024 >>> i = i + 1.7 >>> i 3.2 >>> id(i) 140675668568976
修改代碼聲明兩個相同值的浮點型變量,查看它們的id,發現它們並不是指向同個內存地址,這點和int類型不同(這方面涉及Python內存管理機制,Python對int類型和較短的字符串進行了緩存,無論聲明多少個值相同的變量,實際上都指向同個內存地址。)。
>>> i = 2.5 >>> id(i) 140564351733040 >>> j = 2.5 >>> id(j) 140564351733016
可變類型的話,以list為例。list在append之后,還是指向同個內存地址,因為list是可變類型,可以在原處修改。
>>> a = [1, 2, 3] >>> id(a) 4385327224 >>> a.append(4) >>> id(a) 4385327224
改改代碼,當存在多個值相同的不可變類型變量時,看看它們是不是跟可變類型一樣指向同個內存地址
>>> a = [1, 2, 3] >>> id(a) 4435060856 >>> b = [1, 2, 3] >>> id(b) 4435102392
從運行結果可以看出,雖然a、b的值相同,但是指向的內存地址不同。我們也可以通過b = a 的賦值語句,讓他們指向同個內存地址:
>>> a = [1, 2, 3] >>> id(a) 4435060856 >>> b = [1, 2, 3] >>> id(b) 4435102392 >>> b = a >>> id(b) 4435060856
這個時候需要注意,因為a、b指向同個內存地址,而a、b的類型都是List,可變類型,對a、b任意一個List進行修改,都會影響另外一個List的值。
>>> b.append(4) >>> a [1, 2, 3, 4] >>> b [1, 2, 3, 4] >>> id(a) 4435060856 >>> id(b) 4435060856
代碼中,b變量append(4),對a變量也是影響的。輸出他們的內存地址,還是指向同個內存地址。