python中元類、類對(duì)象、實(shí)例對(duì)象的創(chuàng)建

1、metaclass有兩個(gè)個(gè)作用域 類中、模塊中對(duì)應(yīng)的在本地類作用和在當(dāng)前模塊中所有的類中作用

同時(shí)metacalss的查找順序是 當(dāng)前類中、父類中、當(dāng)前模塊中查找metaclass。

2、查找到metaclass后、首先使用type創(chuàng)建類對(duì)象、之后使用__call__函數(shù)創(chuàng)建類對(duì)象的實(shí)例對(duì)象。

3、創(chuàng)建類對(duì)象的時(shí)候始終使用 type類型的類對(duì)象.__new__函數(shù)創(chuàng)建類對(duì)象、之后調(diào)用 type類型的類對(duì)象.__init__函數(shù)初始化類對(duì)象、但是最終創(chuàng)建類對(duì)象的是type.__new__的元類函數(shù)創(chuàng)建類對(duì)象。其中__new__的參數(shù)包括(元類類型cls,類名,父類元組(),類的屬性字典)。

4、當(dāng)我們使用剛創(chuàng)建的類對(duì)象實(shí)例化時(shí) Foo()時(shí) 調(diào)用時(shí)最終使用的是type.__call__函數(shù)創(chuàng)建的實(shí)例對(duì)象,中間可能會(huì)使用自己定義在元類類型中的__call__函數(shù)來執(zhí)行一些動(dòng)作,但最終還是由type.__call__來創(chuàng)建、type元類直接和c語言對(duì)接【猜測(cè)】

5、我們可以通過修改繼承type元類的元類類型中的 __new__ 、 __init__、 __call__私用方法來操作類對(duì)象的創(chuàng)建、類對(duì)象對(duì)應(yīng)的實(shí)例對(duì)象。

6、所有的__new__函數(shù)必須有返回值、__init__函數(shù)不能有返回值貨值返回值是None。

這是使用type.__call__時(shí)的運(yùn)行代碼、自動(dòng)調(diào)用類對(duì)象的__new__、__init__函數(shù)



import pprintas pp

name='wang'

class meta1(type):

? def __new__(cls, *args, **kwargs):

? ? ? pp.pprint('自己創(chuàng)建元類')

? ? ? return type.__new__(cls, *args, **kwargs)

? def __init__(self,class_name,class_bases,class_attr):

? ? ? # self.name1是類對(duì)象屬性

? ? ? self.name1='zhong'

? ? ? pp.pprint('下面3行是類名、父類、類對(duì)象的屬性')

? ? ? pp.pprint(class_name)

? ? ? pp.pprint(class_bases)

? ? ? pp.pprint(class_attr)

? #? 這里的call會(huì)攔截類中定義的__new__、__init__對(duì)象

? def __call__(self, *args, **kwargs):

? ? ? pp.pprint('call')

? ? ? # self.name1是類對(duì)象屬性

? ? ? pp.pprint(self.name1)

? ? ? pp.pprint(id(self))

? ? ? # 執(zhí)行type.__call__(self, *args, **kwargs)時(shí)候 會(huì)自動(dòng)調(diào)用類對(duì)象中的__new__、__init__函數(shù)

? ? ? obj=type.__call__(self, *args, **kwargs)

? ? ? # obj=object.__new__(self)

# obj=self.__new__(self,*args, **kwargs)

# pp.pprint('++++++++')

# self.__init__(self,*args, **kwargs)

? ? ? pp.pprint(id(obj))

? ? ? return obj

pp.pprint('yyyyyyyyyyyy')

class t1(object,metaclass=meta1):

? def f1(self):

? ? ? pp.pprint('lei de chuang jian ')

? def __new__(cls, *args, **kwargs):

? ? ? print('class? ? ***8')

? ? ? return object.__new__(cls)

? def __init__(self,name):

? ? ? self.name12='jjjj'

? ? ? print('classinit')

pp.pprint('uuuuuuuuuuuuuuuuuu')

if __name__=='__main__':

? pp.pprint('88888')

? # pp.pprint(dir(t1))

? pp.pprint(id(t1))

? ff=t1('cheng')

? pp.pprint(ff.name12)

? pp.pprint(id(ff))

? # ff是類的實(shí)例化對(duì)象,不是類對(duì)象所以沒有name1屬性。

? # pp.pprint(ff.name1)



這是輸出結(jié)果:

'yyyyyyyyyyyy'

'自己創(chuàng)建元類'

'下面3行是類名、父類、類對(duì)象的屬性'

't1'

(<class 'object'>,)

{'__init__': <function t1.__init__ at 0xb77c292c>,

'__module__': '__main__',

'__new__': <function t1.__new__ at 0xb77c28e4>,

'__qualname__': 't1',

'f1': <function t1.f1 at 0xb77c289c>}

'uuuuuuuuuuuuuuuuuu'

'88888'

3078373884

'call'

'zhong'

3078373884

class? ? ***8

classinit

3079005772

'jjjj'

3079005772



參考的文章如下

__call__ 在元類中作用

深入理解python中的元類

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容