1.首先介紹下python的對象引用
1)Python中不存在傳值調用,一切傳遞的都是對象引用,也可以認為是傳址調用。即Python不允許程序員選擇采用傳值或傳引用。Python參數傳遞采用的是“傳對象引用”的方式。實際上,這種方式相當於傳值和傳引用的一種綜合。如果函數參數收到的是一個可變對象(比如字典或者列表)的引用,就能修改對象的原始值——相當於通過“傳引用”來傳遞對象。如果函數收到的是一個不可變對象(比如數字、字符或者元組)的引用,就不能直接修改原始對象——相當於通過"傳值"來傳遞對象。
2)當復制列表或字典時,就復制了對象列表的引用,如果改變引用的值,則修改了原始的參數。
3)為了簡化內存管理,Python通過引用計數機制實現自動垃圾回收功能,Python中的每個對象都有一個引用計數,用來計數該對象在不同場所分別被引用了多少次。每當引用一次Python對象,相應的引用計數就增1,每當消毀一次Python對象,則相應的引用就減1,只有當引用計數為零時,才真正從內存中刪除Python對象。
2. 可變對象與不可變對象的概念與分類
Python在heap中分配的對象分成2類:
不可變對象(immutable object):Number(int、float、bool、complex)、String、Tuple. 采用等效於“傳引用”的方式。
可變對象(mutable object):List、dictionary.采用等效於“傳值”的方式。
3. del 是刪除引用而不是刪除對象,對象由自動垃圾回收機制(GC)刪除
看這個例子:
>>> x = 1 >>> del x >>> x Traceback (most recent call last): File "<pyshell#28>", line 1, in <module> x NameError: name 'x' is not defined >>> x = ['Hello','world'] >>> y = x >>> y ['Hello', 'world'] >>> x ['Hello', 'world'] >>> del x >>> x Traceback (most recent call last): File "<pyshell#32>", line 1, in <module> x NameError: name 'x' is not defined >>> y ['Hello', 'world'] >>>
可以看到x和y指向同一個列表,但是刪除x后,y並沒有受到影響。這是為什么呢?
The reason for this is that you only delete the name,not the list itself,In fact ,there is no way to delete values in python(and you don’t really need to because the python interpreter does it by itself whenever you don’t use the value anymore)
舉個例子,一個數據(比如例子中的列表),就是一個盒子,我們把它賦給一個變量x,就是好像把一個標簽x貼到了盒子上,然后又貼上了y,用它們來代表這個數據,但是用del刪除這個變量x就像是把標有x的標簽給撕了,剩下了y的標簽。
再看一個例子:
shoplist = ['apple', 'mango', 'carrot', 'banana'] print ('The first item I will buy is', shoplist[0]) olditem = shoplist[0] del shoplist[0] #del的是引用,而不是對象
print ('I bought the',olditem) print ('My shopping list is now', shoplist) print(shoplist[0]) 結果為: The first item I will buy is apple I bought the apple My shopping list is now ['mango', 'carrot', 'banana'] mango
實例補充:
#!/usr/bin/evn python # -*- coding:utf-8 -*- # Author: antcolonies
''' python中的內置方法del不同於C語言中的free和C++中的delete (free和delete直接回收內存,當然存儲於該內存的對象也就掛了) Python都是引用,垃圾回收為GC機制 '''
''' if __name__ == '__main__': a = 1 # 對象 1 被 變量a引用,對象1的引用計數器為1 b = a # 對象1 被變量b引用,對象1的引用計數器加1 c = a # 對象1 被變量c引用,對象1的引用計數器加1 del a # 刪除變量a,解除a對1的引用,對象1的引用計數器減1 del b # 刪除變量b,解除b對1的引用,對象1的引用計數器減1 print(c) # 1 '''
if __name__=='__main__': li=['one','two','three','four','five'] # 列表本身不包含數據'one','two','three','four','five',而是包含變量:li[0] li[1] li[2] li[3] li[4]
first=li[0] # 拷貝列表,也不會有數據對象的復制,而是創建新的變量引用
del li[0] print(li) # ['two','three','four','five']
print(first) # one
list1 = li del li print(list1) # ['two', 'three', 'four', 'five'] # print(type(li)) # NameError: name 'li' is not defined
參考鏈接: