Python萬(wàn)物皆對(duì)象理解及源碼學(xué)習(xí)
萬(wàn)物皆對(duì)象
這篇博客的內(nèi)容主要是針對(duì)Python中萬(wàn)物皆對(duì)象的理解,對(duì)Python的類(lèi)型、對(duì)象體系做一個(gè)整體的梳理。
在Python中,一切皆為對(duì)象,一個(gè)整數(shù)是一個(gè)對(duì)象,一個(gè)字符串也是一個(gè)對(duì)象,基本類(lèi)型(如int)也是對(duì)象。Python不再區(qū)別對(duì)待基本類(lèi)型和對(duì)象,所有的基本類(lèi)型內(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
1 類(lèi)型對(duì)象和實(shí)例對(duì)象
Python中的類(lèi)型是一種對(duì)象,稱(chēng)為類(lèi)型對(duì)象。整數(shù)類(lèi)型、字符串類(lèi)型,以及我們通過(guò)class關(guān)鍵字定義的自定義類(lèi)型也是一個(gè)對(duì)象。
通過(guò)類(lèi)實(shí)例化可以得到一個(gè)實(shí)例化對(duì)象,稱(chēng)為實(shí)例對(duì)象
2 類(lèi)型、對(duì)象體系
2.1 元類(lèi)型type
前面我們提到:Python中的類(lèi)型是一種對(duì)象,稱(chēng)為類(lèi)型對(duì)象。那么類(lèi)型對(duì)象的類(lèi)型又是什么呢?
>>> type(int) <class 'type'> >>> int.__class__ <class 'type'>
可以看到,類(lèi)型的類(lèi)型是type,我們稱(chēng)之為元類(lèi)型,但是這個(gè)類(lèi)型比較特殊,它的實(shí)例對(duì)象是類(lèi)型對(duì)象。此外,Python中還有一個(gè)特殊的類(lèi)型object,所有其他類(lèi)型都繼承于object,即object是所有類(lèi)型的基類(lèi)。
圖示如下:
2.2 自定義類(lèi)型
除了Python的內(nèi)置類(lèi)型,我們自定義一個(gè)類(lèi)型MyClass,同樣地,可以得到:
2.3 自定義類(lèi)型子類(lèi)
再定義一個(gè)類(lèi)型MySubClass,該類(lèi)型為MyClass的子類(lèi):
2.4 type和object的關(guān)系
在上述示例中,我們描述了不同對(duì)象、類(lèi)型之間的繼承、類(lèi)型關(guān)系,但是對(duì)于兩個(gè)特殊的類(lèi)型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的類(lèi)型也是type,type本身的類(lèi)型也是type;而type的父類(lèi)也是所有對(duì)象的父類(lèi)——object,而object本身沒(méi)有父類(lèi)。由此我們可以歸納出:
object是所有類(lèi)型的基類(lèi)(除了它自己),本質(zhì)上是一種類(lèi)型,其類(lèi)型是type,同時(shí)也是type的基類(lèi);
type是所有類(lèi)型的類(lèi)型,本質(zhì)上是一種類(lèi)型,其類(lèi)型是它自己,也是object的類(lèi)型;
注:object本身不能有基類(lèi),這是因?yàn)?mdash;—對(duì)于存在繼承關(guān)系的類(lèi),成員屬性和成員方法查找需要回溯繼承鏈,不斷查找基類(lèi)。因此,繼承鏈必須有一個(gè)終點(diǎn),不然就會(huì)死循環(huán)。
最后我們把type和object的關(guān)系補(bǔ)充進(jìn)來(lái):
3 可變對(duì)象與不可變對(duì)象
可變對(duì)象在創(chuàng)建之后,其值可以修改;不可變對(duì)象在創(chuàng)建之后,其值不可以進(jìn)行修改。
以Python中的整數(shù)對(duì)象為例:整數(shù)類(lèi)型是不可變類(lèi)型,整數(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ì)象為例:列表類(lèi)型是可變類(lèi)型,列表對(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ì)保持不變:
4 變長(zhǎng)對(duì)象和定長(zhǎng)對(duì)象
定長(zhǎng)對(duì)象:對(duì)象的內(nèi)存大小一定
邊長(zhǎng)對(duì)象:同一類(lèi)型,不同對(duì)象會(huì)有不同的大小
通過(guò)sys.getsizeof()可以查看一個(gè)對(duì)象的大?。?/p>
>>> 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中采用了類(lèi)似C++中大整數(shù)類(lèi)的思路實(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)的判斷呢?
5 補(bǔ)充
變量名:我們創(chuàng)建對(duì)象時(shí)會(huì)為對(duì)象分配對(duì)應(yīng)的內(nèi)存空間,那么我們將變量名和對(duì)象綁定時(shí),變量又是如何存儲(chǔ)的呢?
詳見(jiàn)Python源碼學(xué)習(xí)筆記:Python作用域與名字空間
以上就是Python萬(wàn)物皆對(duì)象理解及源碼學(xué)習(xí)的詳細(xì)內(nèi)容,更多關(guān)于Python對(duì)象的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Python學(xué)習(xí)之.iloc與.loc的區(qū)別、聯(lián)系和用法
loc和iloc都是pandas工具中定位某一行的函數(shù),下面這篇文章主要給大家介紹了關(guān)于Python學(xué)習(xí)之.iloc與.loc的區(qū)別、聯(lián)系和用法的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-05-05最大K個(gè)數(shù)問(wèn)題的Python版解法總結(jié)
這篇文章主要介紹了最大K個(gè)數(shù)問(wèn)題的Python版解法總結(jié),以最大K個(gè)數(shù)問(wèn)題為基礎(chǔ)的算法題目在面試和各大考試及競(jìng)賽中經(jīng)常出現(xiàn),需要的朋友可以參考下2016-06-06python算法學(xué)習(xí)雙曲嵌入論文方法與代碼解析說(shuō)明
這篇文章主要為大家介紹了python算法學(xué)習(xí)雙曲嵌入論文方法與代碼的實(shí)現(xiàn)解析說(shuō)明,有需要的朋友可以借鑒參考下,希望能夠有所幫助2021-11-11使用python制作一個(gè)為hex文件增加版本號(hào)的腳本實(shí)例
今天小編就為大家分享一篇使用python制作一個(gè)為hex文件增加版本號(hào)的腳本實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-06-06Python實(shí)現(xiàn)微信消息防撤回功能的實(shí)例代碼
這篇文章主要介紹了Python實(shí)現(xiàn)微信消息防撤回 ,需要的朋友可以參考下2019-04-04python讀寫(xiě)刪除復(fù)制文件操作方法詳細(xì)實(shí)例總結(jié)
這篇文章主要介紹了python讀寫(xiě)刪除復(fù)制文件操作方法詳細(xì)實(shí)例總結(jié),需要的朋友可以參考下2021-04-04使用python實(shí)現(xiàn)拉鉤網(wǎng)上的FizzBuzzWhizz問(wèn)題示例
這篇文章主要介紹了使用python實(shí)現(xiàn)拉鉤網(wǎng)上的FizzBuzzWhizz問(wèn)題示例,需要的朋友可以參考下2014-05-05Python如何使用隊(duì)列方式實(shí)現(xiàn)多線程爬蟲(chóng)
這篇文章主要介紹了Python如何使用隊(duì)列方式實(shí)現(xiàn)多線程爬蟲(chóng),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-05-05PyTorch?TensorFlow機(jī)器學(xué)習(xí)框架選擇實(shí)戰(zhàn)
這篇文章主要為大家介紹了PyTorch?TensorFlow機(jī)器學(xué)習(xí)框架選擇實(shí)戰(zhàn),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-10-10