python 元類的理解

2021-09-25 08:58:06 字數 2804 閱讀 5988

簡單的講,元類建立了python中所有的物件。

我們說python是一種動態語言,而動態語言和靜態語言最大的不同,就是函式和類不是編譯時定義的,而是執行時動態建立的

class的定義是執行時動態建立的,而建立class的方法就是使用type()函式

type()函式既可以返回乙個物件的型別,又可以建立出新的型別

要建立乙個class物件,type()函式需要依次傳入3個引數:

class的名稱;

繼承的父類集合,注意python支援多重繼承,如果只有乙個父類,別忘了tuple的單元素寫法;

class的方法名稱與函式繫結,這裡我們把函式helloworld_outside繫結到方法名helloworld上。

>>> from helloworld import helloworld

>>> h = helloworld()

>>> h.helloworld()

hello, world!

>>> print(type(helloworld))

>>> print(type(h))

通過type()函式建立的類和直接寫class是完全一樣的,因為python直譯器遇到class定義時,僅僅是掃瞄一下class定義的語法,然後呼叫type()函式建立出class。

正常情況下,我們都用class ***...來定義類,但是,type()函式也允許我們動態建立出類來,也就是說,動態語言本身支援執行期動態建立類,這和靜態語言有非常大的不同,要在靜態語言執行期建立類,必須構造源**字串再呼叫編譯器,或者借助一些工具生成位元組碼實現,本質上都是動態編譯,會非常複雜。

除了使用type()動態建立類以外,要控制類的建立行為,還可以使用metaclass

metaclass,直譯為元類,簡單的解釋就是:

當我們定義了類以後,就可以根據這個類建立出例項,所以:先定義類,然後建立例項。

但是如果我們想建立出類呢?那就必須根據metaclass建立出類,所以:先定義metaclass,然後建立類

所以,metaclass允許你建立類或者修改類。換句話說,你可以把類看成是metaclass建立出來的「例項」。

class listmetaclass(type):

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

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

class mylist(list, metaclass=listmetaclass):

pass

以上執行結果:

>>> l = mylist()

>>> l.add(1)

>> l

[1]

通過這個例子我們可以看到,自定義我們的mylist分兩步:

1. 建立metaclass,用來建立/修改類

2. 建立實際的mylist class

首先我們來看第一步,建立metaclass:

有了listmetaclass,下乙個問題是如何使用listmetaclass?

首先我們需要先談一談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__函式。

因此,我們在定義類的時候還要指示使用listmetaclass來定製類(即在mylist class定義時,在class宣告處傳入關鍵字引數metaclass=listmetaclass):我們傳入關鍵字引數metaclass後,python會在當前class裡建立屬性__metaclass__,因此它指示python直譯器在建立mylist時,要通過listmetaclass.__new__()來建立,在listmetaclass.__new__()中,我們可以修改類的定義,比如,加上新的方法,然後,返回修改後的定義。

python 元類 python元類深入理解

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

對python元類概念的理解

以下內摘自 python 中的元類程式設計 清單1.老式的python 1.5.2 類工廠 python 1.5.2 0,jun 27 1999,11 23 01 def class with method func class klass pass setattr klass,func.name ...

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

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