從今天起,開始實踐每日一道python面試題,有興趣的小夥伴可以跟着我一起打卡刷起面試題哦,打算建立一個 關於討論 python 面試題的知識星球,可以大家一起討論,每天同步更新微信公衆號文章,以及小夥伴願意加入知識星球的可以掃碼加入哦,自願的哦,希望建立一個有效,高質量的打卡環境,所以我設置付費,當然想免費進入,可以加我微信,我邀約你進入,只有20個名額,名額有限,先到先得
我本着爲人民服務的態度,也是爲我自己持續學習打下基礎吧,這樣我就更加有動力去堅持我想做的事情,不然沒有一點點反饋,很容易前功盡棄的,謝謝各位支持了,在此感謝,文末有二維碼掃描入口
今天要講的是一道簡單,看似很簡單,但是隱含很多的知識點
a = 1
def fun(a):
a = 2
fun(a)
print(a) # 1
a = []
def fun2(a):
a.append(1)
fun2(a)
print(a)
我們都知道,都可以理解是內存中一個對象的“引用”,或者,也可以看似c中void*,通過id
來看引用a
的內存地址可以比較理解:
a = 1
def fun(a):
print(id(a))
a = 2
print(id(a), id(2))
print(id(a), id(1))
fun(a)
print(a) # 1
注:具體的值在不同電腦上運行時可能不同
可以看到,在執行完a = 2
之後,a
引用中保存的值,即內存地址發生變化,由原來1
對象的所在的地址變成了2
這個實體對象的內存地址
而第2個例子a
引用保存的內存值就不會發生變化:
a = []
def fun(a):
print("func_in",id(a)) # func_in 53629256
a.append(1)
print("func_out",id(a)) # func_out 53629256
fun(a)
print(a) # [1]
其實這兩個例子,我們可以在生活中得到體現,就是我們的書櫃,或者衣櫃,這個大的衣櫃其實就是我們所說的引用對象,它佔用多大的空間就那麼大,裏面可以分層,這個分層其實就是我們所說的值,
第二種地址不變的好處就是避免內存的消耗過大,導致內存泄漏等,如果不用的對象,數組等引用類型,記得在不用的時候,給置爲 None,
這裏記住的是類型是屬於對象的,而不是變量。而對象有兩種,“可更改”(mutable)與“不可更改”(immutable)對象。在python中,strings, tuples, 和numbers是不可更改的對象,而 list, dict, set 等則是可以修改的對象。(這就是這個問題的重點)
當一個引用傳遞給函數的時候,函數自動複製一份引用,這個函數裏的引用和外邊的引用沒有半毛關係了.所以第一個例子裏函數把引用指向了一個不可變對象,當函數返回的時候,外面的引用沒半毛感覺.而第二個例子就不一樣了,函數內的引用指向的是可變對象,對它的操作就和定位了指針地址一樣,在內存裏進行修改.
更多精彩的解釋將在知識星球裏面進行討論,我將會整理更多關於引用的問題的文檔,發在知識星球,希望小夥伴可以一起討論,一起學習,一起進步,收穫的將不僅僅是這些,有資源可以互相分享,互相幫助,建立更大的程序員朋友圈,託管資源,等