為了更好的認識函式,我們還要研究值傳遞問題,再研究這個問題之前,我們已經知道了函式之間的值傳遞,是實參變數值傳遞給形參變數,然后讓形參變數在函式內完成相應的功能,但是因為資料型別的不同,這里的值傳遞產生的對實參變數的效果是不同的
1.傳遞資料本質
引數傳遞之間傳遞的肯定是資料,而這種資料本質上是地址值,變數有四個要素:名、值、資料型別、地址值,每個變數在創建時都會在記憶體中開辟一定空間,該空間具有地址值,并在該地址里面存盤資料,Python的變數存盤的資料是地址值,該地址值所代表的是真實資料的地址值,而不是變數的地址值,
1.1不可變資料型別
我們之前介紹過數字、字串、元組它是不可變的,就是說只要在記憶體中創建了該資料,那么它是不變的,創建了數字1,那么數字1是存在的,我們把變數進行運算操作,假設進行加法運算,讓其加1,變為了2,那么這里是創建了一個數字2,數字2也是不可變的,原先的數字1還是存在的,只不過我們的變數中儲存的資料是數字2的地址值了,
圖中的0x-xx是地址假想值,
id函式在作用于變數時,其回傳的是變數指向資料內容的地址值,撰寫程式如下所示:
引數之間資料的傳遞,就是將實參變數的值賦值給形參變數,這里我們說的實參變數的值就是實參資料的地址值,撰寫程式如下所示:
我們通過輸出結果發現,num1、num2、num3所存盤的地址值都是相同的,都為140716513424168,這說明他們都指向同一個資料,也就是數字1,但是經過運算后,num3所存盤的地址值變化了,是因為產生了新資料,新資料的地址賦值給了num3,num3指向了數字2的地址
那么,經過sum函式后,因為num1、num2的地址是沒有發生改變的,所以我們輸出num1和num2它的結果還是1,
這里我們是用數字舉例的,換成字串、元組等都是同樣的道理
1.2可變資料型別
不可變資料型別在記憶體中的表現:當不可變資料型別(數字、字串、元組)的變數需要更新新值時,其創建一個新值,將舊值的地址更換為新值的地址,此時指向發生改變,
可變資料型別,我們目前了解的就是串列、字典,我們可以發現它們都不是一個簡單的資料,而是一組相對復雜的資料集合,資料集合里面包含的資料型別是任意的,就相當于一個倉庫,可變資料型別變數的資料值是倉庫的地址,而我們所說的可變資料型別變數里面的資料更新新值時,不是倉庫地址的改變,而是倉庫內資料元素的改變,
所以,可變資料型別在記憶體中的表現:當可變資料型別(串列、字典)變數需要更新資料元素新值時,其創建一個資料元素新值,將新值的地址放進可變資料型別所指向的倉庫里面,而不是改變可變資料型別變數存盤的倉庫的地址值,其邏輯如下圖所示,
圖中的0x-xx是地址假想值,
我們可以做下驗證,撰寫程式如下所示:
通過輸出結果我們發現,
1.在經過del_first函式之前,輸出串列資料元素為[1,2,3,4],在經過del_first函式之后,輸出串列資料元素為[2,3,4]這說明改變了實參變數list所指向的地址中的內容,形象化理解,就是改變了倉庫里面的內容,
2.在經過del_first函式之前,list變數所存盤的地址值為2113656214912,經過del_first函式之后,list變數所存盤的地址值仍為2113656214912,所以說明list變數經過函式操作后,沒有改變其存盤的地址值,形象化理解,就是沒有改變倉庫的地址
3.在經過del_first函式之前,串列資料元素0所存盤的地址為140712759325480,串列資料元素1所存盤的地址為140712759325512,在經過del_first函式之后,串列資料0所存盤的地址為原先串列資料元素1存盤的地址140712759325512,也就是經過洗掉第一個資料元素的操作后,所有資料元素都依次往前排列,形象化理解,就是把倉庫中第一個位置的物品拿出來,然后把其他的物品依次往前挪一個位置,
這里我們是用串列舉例的,換成字典等其他可變資料型別都是同樣的道理
1.3總結
不可變資料型別的實參變數,經過函式操作之后,不會改變其原有內容
可變資料型別的實參變數,經過函式操作之后,會改變其原有內容
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/555546.html
標籤:其他
上一篇:Spring Boot 優雅實作多租戶架構,so easy~!
下一篇:返回列表