對(duì)象:
內(nèi)存中存放的一塊邏輯的整體數(shù)據(jù)對(duì)象具有唯一的標(biāo)識(shí)符,對(duì)象包括屬性(Properties)和方法(Methods),屬性就是需要記憶的信息,方法就是對(duì)象
能夠提供的服務(wù)。在面向?qū)ο?Object Oriented) 的軟件中,對(duì)象(Object)是某一個(gè)類(lèi)(Class)的實(shí)例(Instance)。在python中輸入dir(2)
可以知道,在python中2并不是簡(jiǎn)單的一個(gè)整數(shù),而且包含了很多內(nèi)置的方法。
引用:
引用像指針一樣指向一塊內(nèi)存空間,跟c語(yǔ)言中的指針相似。
舉例:
整數(shù)對(duì)象
簡(jiǎn)單的賦值語(yǔ)句 a = 10000, a 指向了 10000 所在的那塊內(nèi)存。a 引用的對(duì)象就是存放 1 的內(nèi)存地址。is 判斷兩個(gè)變量是否引用同一個(gè)對(duì)象,id()取得對(duì)象的內(nèi)存地址
a = 10000
b = 10000
print a is b
輸出是 False, 可以知道a,b是兩個(gè)不同的對(duì)象,每次創(chuàng)建都會(huì)申請(qǐng)新的內(nèi)存
a = 1
b = 1
print a is b
輸出是 True,a,b又是相同的對(duì)象了。這是因?yàn)樵趐ython啟動(dòng)的時(shí)候,常用的常數(shù)[-5, 256]就建立好,不銷(xiāo)毀的對(duì)象,也就是a,b都引用相同的>一塊內(nèi)存(存放10000的內(nèi)存),每次創(chuàng)建這個(gè)范圍內(nèi)的整數(shù)對(duì)象不會(huì)申請(qǐng)新的內(nèi)存。這是個(gè)設(shè)計(jì)上的均衡,用一些內(nèi)存的浪費(fèi),來(lái)提高大部分程序>的運(yùn)行速度
容器對(duì)象
python中容器(可以包含其他對(duì)象的對(duì)象)中存放的對(duì)象實(shí)際上都是引用
In [17]: a = [[]] * 5
In [18]: a
Out[18]: [[], [], [], [], []]
In [19]: a[1].append(0)
In [20]: a
Out[20]: [[0], [0], [0], [0], [0]]
In [21]: a[0] is a[1]
Out[21]: True
a 列表有五個(gè)相同的元素,這五個(gè)元素都是對(duì)同一個(gè)空列表的引用(21行),所以改變其中任何一個(gè)元素(不改變對(duì)象引用的情況下),所有的五個(gè)元>素都會(huì)同時(shí)進(jìn)行改變
list 是可變對(duì)象,在list擴(kuò)容的時(shí)候有幾種方法
In [6]: a = [1]
In [7]: id(a)
Out[7]: 28048488
In [8]: a = a + [2]
In [9]: a
Out[9]: [1, 2]
In [10]: id(a)
Out[10]: 28047696
可以看出使用 + 修改列表,創(chuàng)建了新的列表(對(duì)象),a 已經(jīng)不是原先那個(gè)對(duì)象,不存放在原先那個(gè)內(nèi)存地址了,進(jìn)行了大量的內(nèi)存復(fù)制
In [21]: a = [1]
In [22]: id(a)
Out[22]: 20913832
In [23]: a += [2]
In [24]: id(a)
Out[24]: 20913832
使用 += 修改列表,并沒(méi)有創(chuàng)建新的列表(對(duì)象),還存放在原先那個(gè)地址。(extend 與 += 幾乎相同,只是extend多了調(diào)用函數(shù)的時(shí)間)。
In [29]: a = [1]
In [30]: id(a)
Out[30]: 28048704
In [31]: a.append(2)
In [32]: id(a)
Out[32]: 28048704
使用 append 修改列表,也沒(méi)有創(chuàng)建新的列表,也是存放在原先那個(gè)地址。append會(huì)進(jìn)行提前的內(nèi)存申請(qǐng),擴(kuò)容時(shí)會(huì)更快。但是 append 只能進(jìn)行單個(gè)元素的擴(kuò)容,內(nèi)存消耗較大。
所以列表擴(kuò)容的時(shí)候盡量使用 extend 或者 append(當(dāng)然 list 如果進(jìn)行頻繁大量空間的擴(kuò)容,肯定會(huì)造成效率問(wèn)題)。
string 和 tuple 都是不可變對(duì)象,所以在進(jìn)行改變的時(shí)候肯定都會(huì)創(chuàng)建新的對(duì)象。(根據(jù)這個(gè)原理,可以思考下為什么 string 進(jìn)行合并的時(shí)候?yàn)槭裁唇ㄗh用join)
函數(shù)對(duì)象
在 python 中函數(shù)也是對(duì)象,所以我們可以像整數(shù)賦值一樣,將函數(shù)賦值給一個(gè)變量,將函數(shù)作為參數(shù)傳遞給另一個(gè)函數(shù),我覺(jué)得這也是為什么python中存在 decorator 的一個(gè)原因
參考:
http://zh.wikipedia.org/wiki/%E5%AF%B9%E8%B1%A1_(%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6
python群 22507237 的 @冒泡 大神