聲明:本人是一個初學者,博客內容基本也是一些基礎的東西,若是說的有什麼問題歡迎糾正。python
許多人初學python以前應該也學習過其餘的語言,好比博大精深的c語言,筆者在學習python以前就學習過c語言,衆所周知的是c語言是一個面向過程的語言,而python是屬於面向對象的語言,代表兩者在編程時會有所不一樣。既然要說python的數據存儲認識,爲何要提到c語言呢?下面介紹筆者在初學python時類比c語言出現的一些誤區。程序員
筆者學習c語言時常常性的想起一句話:指針即地址。在c語言的編程中傳遞參數的副本仍是本來是在參數傳遞時控制,若是想給函數傳遞本來就在變量以前加一個取地址符號(&),傳遞副本則直接寫變量的名字便可。傳遞本來和傳遞副本的區別在於:傳遞副本時在函數中所作的修改不會在函數以外改變,傳遞本來則在函數中所作的修改也會對函數以外起做用。在剛開始學習python時常常會和c語言類比,將可變數據類型的引用類比成c語言中的傳遞本來,將不可變數據類型的引用類比成c語言中的傳遞副本。表面上理解是沒有任何問題,可是這個想法在本質上仍是錯誤的,下面會舉例解釋。編程
python中是不容許程序員直接選擇是值傳遞仍是地址傳遞(傳遞副本仍是傳遞本來)。python中能夠說只有一種傳遞參數的方式,那就是引用傳遞。只不過基於對象的不一樣,大體又能夠分爲不可變類型的引用傳遞和可變類型的引用傳遞。可變類型的引用能夠有多個,可是儲存信息的地址只有一個,因此當經過多個應用中的某個引用對存儲內容進行修改時,其實都是對一個地址修改,因此會呈現出全部引用都變化的效果。不可變類型的引用只有一個,當你嘗試在函數中改變這個變量的值時(即例如 變量名 = 新的值),python會新建一個變量引用用來指向這個新的值(使用id函數比較兩個地址會返回False),兩個對象雖然名字同樣,可是它們兩個是沒有任何關係的,因此呈現出的效果就是原來的不可變對象不變。編程語言
可變類型(mutable):列表,字典函數
不可變類型(unmutable):數字,字符串,元組學習
這裏的可變不可變,是指內存中的那塊內容(value)是否能夠被改變spa
python中的del函數的做用是刪除一個對象的某個引用,而python的回收機制是當指向某對象引用爲0時就將該對象回收。因此del在操做只有一個引用的對象時相似於直接刪除對象的效果。指針
下面的代碼爲舉例使用del函數刪除a_list列表中的是三倍數的元素時出現的刪除不了的情況。code
def change(a_list_change): for data in a_list_change: if data % 3 == 0: del data a_list = [1, 3, 5, 7, 9, 11, 13, 15] change(a_list) print(a_list)
輸出的結果爲[1, 3, 5, 7, 9, 11, 13, 15]。緣由在於del只刪除了for循環迭代中產生的指向a_list_change元素的data引用,因此a_list的元素並不會被刪除。對象
將其中的語句del data 改成a_list_change.remove(data)後的代碼以下。
def change(a_list_change): for data in a_list_change: if data % 3 == 0: a_list_change.remove(data) a_list = [1, 3, 5, 7, 9, 11, 13, 15] change(a_list) print(a_list)
此時輸出的結果爲[1, 5, 7, 11, 13],可見已經把是三倍數的數字刪除了。
此時若是是c語言的思惟方式就沒法解釋這種刪除引用的現象了。
順便一提python是一種足夠智能的編程語言,當不可變類型int足夠小,並且有多個引用指向它的時候,比較他們的id地址,會出現相同的狀況,由於python爲了節省內存,會出現這樣的狀況,可是不會影響用戶的使用。