嘗試用python的概念,解釋python自身的底層原理
class PyObject:
def __init__(
self,
ob_refcnt=1,
ob_type=None
):
self.ob_refcnt: int = ob_refcnt
self.ob_type: PyTypeObject = ob_type
這是一個C語言的結(jié)構(gòu)體秦爆,現(xiàn)在我們把它用python的形式展現(xiàn)出來淘正。一切python對象爆雹,底層實習(xí)都會包含PyObject。因為C語言可以強(qiáng)轉(zhuǎn)和內(nèi)存對齊勺三。所以實際上他是類似于python的繼承雷滚。如果你熟悉java的向上轉(zhuǎn)型,那么理解起來會很容易吗坚。
所以一切Python對象都可以用PyObject來表示祈远,它們之間的不同是,在PyObject之外多了一些額外的不同數(shù)據(jù)刻蚯。
PyObject記錄了兩個信息:
- ob_refcnt 引用計數(shù)绊含,默認(rèn)為1
- ob_type 對象的類型,其指向一個類對象
好炊汹,現(xiàn)在讓我們回想躬充。python的類也是一個對象
class PyTypeObject(PyObject):
def __init__(
self,
new=None,
init=None,
call=None,
ob_refcnt=1,
ob_type=None
):
super().__init__(ob_refcnt, ob_type)
self.new = new
self.init = init
self.call = call
我們建立一個這樣的類,他是PyObject的擴(kuò)展讨便,額外包含了很多東西充甚。我們這里給它加入三個方法,new, init, call霸褒。
我們嘗試建立一個類
new_cls = PyTypeObject(ob_type=???)
def class_new(cls):
return PyObject(ob_type=cls)
def class_init(self):
pass
def class_call(cls, *args, **kwargs):
instance = cls.new(cls)
cls.init(instance, *args, **kwargs)
return instance
new_cls.new = class_new
new_cls.init = class_init
new_cls.call = class_call
這樣這個類具有產(chǎn)生實例的能力了伴找,我們只需要調(diào)用他的call()方法,一個PyObject實例便由此產(chǎn)生废菱。且其ob_type技矮,指向這個類。
不過這里的new, init, call不能完全對應(yīng)__ new __, __ init __, __ call __ 殊轴。這里只是底層的表示衰倦。像python中類中定義的 __ call __ 實際上是實例的 __ call __,而不是類自身的旁理。
我們會發(fā)現(xiàn)一個問題
第一句中定義類對象的時候樊零,我們沒有指出ob_type,也就是類的類型孽文。
如果你了解python驻襟,那么一定知道元類夺艰,實際上元類就是這個類的ob_type。
我們知道元類的可以產(chǎn)生類沉衣。
同時元類本身也是一個類郁副,我們可以看成一個特殊的類。
我們可以來create一個type對象厢蒜,在全局作用域上霞势。
PyType_Type = PyTypeObject()
def type_new(msc: PyTypeObject):
return PyTypeObject(ob_type=msc)
def type_init(new_cls: PyTypeObject, **new_kwargs):
def class_new(cls):
return PyObject(ob_type=cls)
def class_init(self):
pass
def class_call(cls, *args, **kwargs):
instance = cls.new(cls)
cls.init(instance, *args, **kwargs)
return instance
new_cls.new = class_new
new_cls.init = class_init
new_cls.call = class_call
for k, v in new_kwargs:
setattr(new_cls, k, v)
def type_call(msc: PyTypeObject, **kwargs):
cls: PyTypeObject = msc.new(msc)
msc.init(cls, **kwargs)
return cls
PyType_Type.new = type_new
PyType_Type.init = type_init
PyType_Type.call = type_call
PyType_Type.ob_type = PyType_Type
把之前普通類定義的代碼放到其中,這樣一個會產(chǎn)生類對象的斑鸦。
因為python沒有指針愕贡,無法做到
PyType_Type = PyTypeObject(ob_type=PyType_Type)
所以我們在對象建立后,再將其指向自己巷屿。
這個PyType_Type固以,實際上就是python中的type對象。
當(dāng)然我們知道嘱巾,還有個全局的對象是object憨琳。
我們現(xiàn)在建一個就好了。
PyBaseObject_Type = PyType_Type.call(PyType_Type)
這樣一組低配的type和object就建立好了
還有一點旬昭,就是繼承篙螟,我們在此忽略了這點。
如果你了解過元類问拘,一定知道一個特別繞的概念
object的類型是type遍略,type的父類是object
實際上我們在上述兩個結(jié)構(gòu)體對象建立只有,將指針互相指向?qū)Ψ奖憧梢詫崿F(xiàn)骤坐。
NewClass = PyType_Type.call(PyType_Type)
print(NewClass)
NewObject = NewClass.call(NewClass)
print(NewObject)