Python探路 元類

2021-09-24 02:57:33 字數 2317 閱讀 1752

首先,對於python來說,萬物皆物件,類物件是物件,其實類本質也是物件,這一點是和其它語言不一樣的地方,在大多數程式語言中,類就是一組用來描述如何生成乙個物件的**段。

在python世界中,等級很像道中的道生一,一生二,二生三,三生萬物。分五個等級,我們一層一層的往下:

1、道即是 type

2、一即是 metaclass(元類,或者叫類生成器)

3、二即是 class(類,或者叫例項生成器)

4、三即是 instance(例項)

5、萬物即是 例項的各種屬性與方法,我們平常使用python時,呼叫的就是它們。

正常情況下,我們都是用class去建立乙個類,但是我們也可以用type去建立乙個類,大概的方式是這樣的:

def fn(self, name='world'): # 假如我們有乙個函式叫fn

print('hello, %s.' % name)

hello = type('hello', (object,), dict(say_hello=fn))

定義:type(類名, 父類的元組(針對繼承的情況,可以為空),包含屬性的字典(名稱和值))

上面就變成了type生成類,道生二,其實type也是元類,只不過type也可以生成元類。

正常我們生成乙個類的流程是這樣的,通過type去生成元類,再通過元類去生成類。

# 道生一:傳入type

class saymetaclass(type):

# 傳入三大永恆命題:類名稱、父類、屬性

def __new__(cls, name, bases, attrs):

# 創造「天賦」

attrs['say_'+name] = lambda self,value,saying=name: print(saying+','+value+'!')

# 傳承三大永恆命題:類名稱、父類、屬性

return type.__new__(cls, name, bases, attrs)

# 一生二:建立類

class hello(object, metaclass=saymetaclass):

pass

# 二生三:建立實列

hello = hello()

# 三生萬物:呼叫例項方法

hello.say_hello('world!')

首先我們需要先談一談python建立class的機制:

當建立class的時候,python會先檢查當前類中有沒有__metaclass__,如果有,就用此方法建立物件;如果沒有,則會一級一級的檢查父類中有沒有__metaclass__,用來建立物件。建立的這個「物件」,就是當前的這個類。如果當前類和父類都沒有,則會在當前package中尋找__metaclass__方法,如果還沒有,則會呼叫自己隱藏的的type函式來建立物件

值得注意的是,如果我們在做類的定義時,在class宣告處傳入關鍵字metaclass=listmetaclass,那麼如果傳入的這個metaclass有__call__函式,這個__call__函式將會覆蓋掉mylist class的__new__函式。這是為什麼呢?請大家回想一下,當我們例項化mylist的時候,用的語句是l1=mylist(),而我們知道,__call__函式的作用是能讓類例項化後的物件能夠像函式一樣被呼叫。也就是說mylist是listmetaclass例項化後的物件,而mylist()呼叫的就是listmetaclass的__call__函式。另外,值得一提的是,如果class宣告處,我們是讓mylist繼承listmetaclass,那麼listmetaclass的__call__函式將不會覆蓋掉mylist的__new__函式。

很多人會問,我們生成類的時候,是不會去使用metaclass這個引數的,這是因為我們建立類的流程是這樣的:

1、hello中有__metaclass__這個屬性嗎?如果是,python會在記憶體中通過__metaclass__建立乙個名字為foo的類物件(我說的是類物件,請緊跟我的思路)。

2、如果python沒有找到__metaclass__,它會繼續在父類中尋找__metaclass__屬性,並嘗試做和前面同樣的操作。

3、如果python在任何父類中都找不到__metaclass__,它就會在模組層次中去尋找__metaclass__,並嘗試做同樣的操作。

4、如果還是找不到__metaclass__,python就會用內建的type來建立這個類物件。

Python探路 多重繼承

多重繼承都會讓python初學者很疑惑,哪怕當時看完,過一段時間也就遺忘了,因此寫下了本文,希望藉此能夠讓python初學者能夠比較深刻的記住。多重繼承查詢父類的方法有兩種 1 深度優先 針對經典類,即python2.2之前和python2.7 2 c3演算法 針對新式類 一 深度優先 可從某個定點...

python 元類 python元類深入理解

1.python 中的類 在python中,類也是乙個物件,只不過這個物件擁有生成例項的能力,我們一般使用class 來定義乙個類,在python直譯器執行到這個地方的時候會自動建立出這個物件,python也為我們提供了手動建立類的方法,type type 這個方法對我們來說並不陌生,我們所熟知的用...

python元類的使用 Python的元類如何使用

這次給大家帶來python的元類如何使用,使用python元類的注意事項有哪些,下面就是實戰案例,一起來看一下。今天我的任務就是徹底明白什麼是元類,一起看看。要搞懂元類,我們還是先從物件說起。python 一切皆物件,這句話你一定有聽說過 現在你就聽說了 乙個數字是物件,乙個字串是物件,乙個列表是物...