您好,登錄后才能下訂單哦!
這篇文章主要講解了“Python萬(wàn)物皆對(duì)象源碼分析”,文中的講解內(nèi)容簡(jiǎn)單清晰,易于學(xué)習(xí)與理解,下面請(qǐng)大家跟著小編的思路慢慢深入,一起來(lái)研究和學(xué)習(xí)“Python萬(wàn)物皆對(duì)象源碼分析”吧!
這篇博客的內(nèi)容主要是針對(duì)Python中萬(wàn)物皆對(duì)象的理解,對(duì)Python的類型、對(duì)象體系做一個(gè)整體的梳理。
在Python中,一切皆為對(duì)象,一個(gè)整數(shù)是一個(gè)對(duì)象,一個(gè)字符串也是一個(gè)對(duì)象,基本類型(如int)也是對(duì)象。Python不再區(qū)別對(duì)待基本類型和對(duì)象,所有的基本類型內(nèi)部均由對(duì)象實(shí)現(xiàn)。
>>> a = int >>> b = 1 >>> id(a) 140734789683952 >>> id(int) 140734789683952 >>> a <class 'int'> >>> id(b) 2421963817200 >>> id(1) 2421963817200 >>> b 1
Python中的類型是一種對(duì)象,稱為類型對(duì)象。整數(shù)類型、字符串類型,以及我們通過(guò)class關(guān)鍵字定義的自定義類型也是一個(gè)對(duì)象。
通過(guò)類實(shí)例化可以得到一個(gè)實(shí)例化對(duì)象,稱為實(shí)例對(duì)象
前面我們提到:Python中的類型是一種對(duì)象,稱為類型對(duì)象。那么類型對(duì)象的類型又是什么呢?
>>> type(int) <class 'type'> >>> int.__class__ <class 'type'>
可以看到,類型的類型是type,我們稱之為元類型,但是這個(gè)類型比較特殊,它的實(shí)例對(duì)象是類型對(duì)象。此外,Python中還有一個(gè)特殊的類型object,所有其他類型都繼承于object,即object是所有類型的基類。
圖示如下:
除了Python的內(nèi)置類型,我們自定義一個(gè)類型MyClass,同樣地,可以得到:
再定義一個(gè)類型MySubClass,該類型為MyClass的子類:
在上述示例中,我們描述了不同對(duì)象、類型之間的繼承、類型關(guān)系,但是對(duì)于兩個(gè)特殊的類型type和object的關(guān)系并沒(méi)有指出,我們先來(lái)打印看一下:
>>> type(type) <class 'type'> >>> type(object) <class 'type'> >>> type.__base__ <class 'object'> >>> object.__base__ >>> print(object.__base__) None
可以看到:object的類型也是type,type本身的類型也是type;而type的父類也是所有對(duì)象的父類——object,而object本身沒(méi)有父類。由此我們可以歸納出:
object是所有類型的基類(除了它自己),本質(zhì)上是一種類型,其類型是type,同時(shí)也是type的基類;
type是所有類型的類型,本質(zhì)上是一種類型,其類型是它自己,也是object的類型;
注:object本身不能有基類,這是因?yàn)?amp;mdash;—對(duì)于存在繼承關(guān)系的類,成員屬性和成員方法查找需要回溯繼承鏈,不斷查找基類。因此,繼承鏈必須有一個(gè)終點(diǎn),不然就會(huì)死循環(huán)。
最后我們把type和object的關(guān)系補(bǔ)充進(jìn)來(lái):
可變對(duì)象在創(chuàng)建之后,其值可以修改;不可變對(duì)象在創(chuàng)建之后,其值不可以進(jìn)行修改。
以Python中的整數(shù)對(duì)象為例:整數(shù)類型是不可變類型,整數(shù)對(duì)象是不可變對(duì)象?!靶薷恼麛?shù)對(duì)象”時(shí),Python將以新值創(chuàng)建一個(gè)新對(duì)象,變量名與新對(duì)象進(jìn)行綁定,舊對(duì)象如果沒(méi)有其他引用,則會(huì)被釋放(通過(guò)“小整數(shù)池”進(jìn)行創(chuàng)建回收優(yōu)化,具體后續(xù)介紹,這里先按下不表,后續(xù)會(huì)補(bǔ)充)。
圖示如下:
以Python中的列表對(duì)象為例:列表類型是可變類型,列表對(duì)象是可變對(duì)象。列表對(duì)象內(nèi)部會(huì)維護(hù)一個(gè)動(dòng)態(tài)數(shù)組,存儲(chǔ)元素對(duì)象的指針,列表對(duì)象再增減對(duì)象的時(shí)候,會(huì)修改該數(shù)組,而列表對(duì)象的“頭部”(后續(xù)會(huì)詳細(xì)介紹)會(huì)保持不變:
定長(zhǎng)對(duì)象:對(duì)象的內(nèi)存大小一定
邊長(zhǎng)對(duì)象:同一類型,不同對(duì)象會(huì)有不同的大小
通過(guò)sys.getsizeof()可以查看一個(gè)對(duì)象的大小:
>>> import sys >>> a = 1 >>> b = 1111111111111111111111111111111111111111111111111111111111 >>> c = 1.0 >>> d = 1.00000000000000000000000000000000000000000000000000000001 >>> sys.getsizeof(a) 28 >>> sys.getsizeof(b) 52 >>> sys.getsizeof(c) 24 >>> sys.getsizeof(d) 24
整數(shù)對(duì)象是變長(zhǎng)對(duì)象:固定位數(shù)的整數(shù)能夠表示的范圍是有限的,故整數(shù)對(duì)象會(huì)隨著自身的數(shù)值大小而改變自身內(nèi)存大小。在Python中采用了類似C++中大整數(shù)類的思路實(shí)現(xiàn)整數(shù)對(duì)象,通過(guò)串聯(lián)多個(gè)普通32位整數(shù)來(lái)支持更大的數(shù)值范圍(詳細(xì)源碼后續(xù)介紹)。
浮點(diǎn)數(shù)對(duì)象是定長(zhǎng)對(duì)象:根據(jù)機(jī)組的知識(shí),我們用32位表示單精度浮點(diǎn)數(shù),用64位表示雙精度浮點(diǎn)數(shù),它們都是定長(zhǎng)的。在Python中,浮點(diǎn)數(shù)背后是由一個(gè)double來(lái)實(shí)現(xiàn)的,就算表示很大的數(shù),浮點(diǎn)數(shù)對(duì)象的大小也不變(這樣做的代價(jià)是犧牲了精度)。當(dāng)然,浮點(diǎn)數(shù)也是有大小限制的,可以思考下:我們通過(guò)float()將一個(gè)很大的int轉(zhuǎn)化為float時(shí),是否會(huì)報(bào)錯(cuò)?Python底層是否做了相應(yīng)的判斷呢?
變量名:我們創(chuàng)建對(duì)象時(shí)會(huì)為對(duì)象分配對(duì)應(yīng)的內(nèi)存空間,那么我們將變量名和對(duì)象綁定時(shí),變量又是如何存儲(chǔ)的呢?
感謝各位的閱讀,以上就是“Python萬(wàn)物皆對(duì)象源碼分析”的內(nèi)容了,經(jīng)過(guò)本文的學(xué)習(xí)后,相信大家對(duì)Python萬(wàn)物皆對(duì)象源碼分析這一問(wèn)題有了更深刻的體會(huì),具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是億速云,小編將為大家推送更多相關(guān)知識(shí)點(diǎn)的文章,歡迎關(guān)注!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。