Python源碼分析(三): 再次探討 Python 中的類型與對(duì)象
源碼面前, 毫無秘密 --- 魯迅(bushi
我們知道 Python 是一門面向?qū)ο蟮哪_本語言, 在編程語言中, 一種是自頂向下,?直接從數(shù)學(xué)開始推導(dǎo)出程序,?這基于邱奇的lambda演算, 這就是函數(shù)式編程。另一種是自底向上, 這基于圖靈的理論,從計(jì)算機(jī)運(yùn)行原理和底層匯編出發(fā)逐步封裝使得問題變得更簡(jiǎn)單,運(yùn)用面向?qū)ο缶幊虂砉芾砦覀兊臓顟B(tài)。而 Python 就是這樣一門簡(jiǎn)潔的面向?qū)ο笳Z言(當(dāng)然還有 Ruby), Python is programmer's best friend!
在 Python 的世界一切皆對(duì)象,不論是整數(shù),還是字符串,甚至連類型、函數(shù)等都是一種對(duì)象。
我們?cè)賮砜纯磳?duì)象的最基本形態(tài) --?PyObject 結(jié)構(gòu)體的定義:

類型對(duì)象也是對(duì)象
我們來看看 _typeobject 的定義, 這個(gè)結(jié)構(gòu)體里面定義了類型名稱, 類型支持的操作與內(nèi)存分配的操作:
我們現(xiàn)在就從 PyObject 開始組合與封裝出復(fù)雜的對(duì)象
PyVarObject可變長對(duì)象
我們看到 PyVarObject 里面包括了 PyObject (沒錯(cuò), 這就是用 c 語言實(shí)現(xiàn)繼承和多態(tài)的方法), 而且還新增了一個(gè) ob_size 的屬性來記錄當(dāng)前的長度:

有了可變長對(duì)象, 我們?cè)?Objects/typeobject.c?中看到 Python 會(huì)在運(yùn)行時(shí)創(chuàng)建一個(gè) PyType_Type 的對(duì)象:
實(shí)際上, Python中的類型對(duì)象最終都會(huì)引用到PyType_Type中, 下面是一個(gè)整數(shù)的類型對(duì)象在運(yùn)行時(shí)結(jié)構(gòu)體的狀態(tài):

所以我們可以得出結(jié)論:PyType_Type
?在類型機(jī)制中至關(guān)重要,所有用戶自定義?class
?所 對(duì)應(yīng)的?PyTypeObject
?對(duì)象都是通過?PyType_Type
創(chuàng)建的!, 并且 PyType_Type 也是一個(gè)可變長對(duì)象,這再次體現(xiàn)出了 Python 動(dòng)態(tài)語言的特性。
從 PyTypeObject?到其它對(duì)象類型
我們來看看 PyLong_Type 在運(yùn)行時(shí)創(chuàng)建的源碼:
我們看到 PyLong_Type 就是一個(gè) PyTypeObject 類型對(duì)象。再來看看源碼中經(jīng)常出現(xiàn)的PyVarObject_HEAD_INIT宏:
這個(gè)宏的作用初始化 PyTypeObject 的 PyObject 部分 (ob_refcnt?初始化為 1, ob_type 指向 PyType_Type, 可變對(duì)象的 size 為 1)。
接下來打算分析一波?dict, set, list 等數(shù)據(jù)類型的實(shí)現(xiàn), 再深入研究一下 VM internal 中的對(duì)象, 順便復(fù)習(xí)一下算法和數(shù)據(jù)結(jié)構(gòu), 并且學(xué)習(xí)一下龜叔寫代碼的風(fēng)格(只是希望能模仿一下)。