寫在前面
“Python 一切皆對象沐鼠!”中的“對象”是“廣義對象”绳军,即萬物皆對象五督!
本文所要討論的“可變對象”和“不可變對象”中的“對象”是“狹義對象”彰导,即在內(nèi)存中真正存在的對象蛔翅!
“不可變對象”和“可變對象”的區(qū)別
不可變對象:對象一旦在內(nèi)存中生成后,它的值是不能被修改的位谋,若要得到“不同值”的新對象山析,只能通過重新分配新內(nèi)存創(chuàng)建新對象的方法!
可變對象:對象在內(nèi)存中生成后掏父,它的值可以被修改盖腿!若要得到“不同值”的新對象,既可以通過重新分配新內(nèi)存創(chuàng)建新對象的方法损同,也可以在原對象的基礎(chǔ)上直接修改值翩腐!(注意,可變對象并不意味著一定要在原對象上進行操作膏燃!)
下圖清晰展示了兩者的區(qū)別茂卦。對于不可變對象,執(zhí)行a=1時组哩,先生成一個對象1等龙,然后將a指向該對象;執(zhí)行a=2時伶贰,在新內(nèi)存中生成一個對象2蛛砰,然后將a指向這個新對象,如果原對象1沒有其他變量指向它黍衙,那么將被銷毀泥畅,釋放內(nèi)存!
對于可變對象琅翻,可在原值的基礎(chǔ)上進行修改位仁,無需生成新對象就可以得到新值。
不可變對象:int方椎、字符串(str)聂抢、float、元組(tuple)棠众、數(shù)值型(number)琳疏、空(None)
可變對象:列表(list)、字典(dict)、集合(set)
為什么要分可變和不可變對象空盼?
廖雪峰博客:“為什么要設(shè)計str疮薇、None這樣的不變對象呢?因為不變對象一旦創(chuàng)建我注,對象內(nèi)部的數(shù)據(jù)就不能修改按咒,這樣就減少了由于修改數(shù)據(jù)導(dǎo)致的錯誤。此外但骨,由于對象不變励七,多任務(wù)環(huán)境下同時讀取對象不需要加鎖,同時讀一點問題都沒有奔缠。我們在編寫程序時掠抬,如果可以設(shè)計一個不變對象,那就盡量設(shè)計成不變對象校哎×讲ǎ”
★★必須要注意的問題
前面已經(jīng)提到,對于不可變對象闷哆,是不能在原對象的基礎(chǔ)上修改值的腰奋;對于可變對象,則可以在原對象的基礎(chǔ)上修改值抱怔,但這并不意味著所有操作都要在原對象的基礎(chǔ)上進行劣坊!見下例:
(情況1)在原對象上修改
>>>a = [1,2,3]
>>>print(id(a))
>>>a += [4]
>>>print(id(a))
>>>print(a)
36220232 #原對象地址
36220232 #依舊是原對象地址
[1, 2, 3, 4]
(情況2)在產(chǎn)生了新對象
a = [1,2,3]
print(id(a))
a = a + [4]
print(id(a))
print(a)
36244296 #原對象地址
36244232 #產(chǎn)生了新對象
[1, 2, 3, 4]
上面兩種情況,唯一的差別是前者a += [4]屈留,后者a = a + [4]局冰,結(jié)果都得到了新的列表[1,2,3,4]。但兩種情況的內(nèi)存處理過程是完全不同的灌危,前者在原對象上進行康二,而后者產(chǎn)生了新對象!
這兩個例子的目的是為了說明勇蝙,對于可變對象而言沫勿,有各種各樣的方式可以對其進行操作(增加、刪除浅蚪、插入藕帜、排序、反向等等)惜傲,這些操作有些會在原對象上進行,有些會新建一個新對象贝攒,編程時必須要搞清楚具體情況盗誊!