Python基礎到高階 元類metaclass

2022-03-30 19:50:14 字數 3369 閱讀 7449

一切源自於一句話:python中一切皆為物件。讓我們先定義乙個類,然後逐步分析

class

oldboyteacher(object):

school='

oldboy

'def

__init__

(self,name,age):

self.name=name

self.age=age

defsay(self):

print('

%s says welcome to the oldboy to learn python

' %self.name)

所有的物件都是例項化或者說呼叫類而得到的(呼叫類的過程稱為類的例項化),比如物件t1是呼叫類oldboyteacher得到的

t1=oldboyteacher('

egon

',18)

print(type(t1)) #

檢視物件t1的類是

如果一切皆為物件,那麼類oldboyteacher本質也是乙個物件,既然所有的物件都是呼叫類得到的,那麼 oldboyteacher 類必然也是呼叫了乙個類得到的,這個類稱為元類

於是我們可以推導出===>產生oldboyteacher的過程一定發生了:oldboyteacher=元類(...)

print(type(oldboyteacher)) #

結果為,證明是呼叫了type這個元類而產生的oldboyteacher,即預設的元類為type

上文我們基於python中一切皆為物件的概念分析出:我們用class關鍵字定義的類本身也是乙個物件,負責產生該物件的類稱之為元類(元類可以簡稱為類的類),內建的元類為type

class關鍵字在幫我們建立類時,必然幫我們呼叫了元類oldboyteacher=type(...),那呼叫type時傳入的引數是什麼呢?必然是類的關鍵組成部分,乙個類有三大組成部分,分別是

1、類名class_name='oldboyteacher'

2、基類們class_bases=(object,)

3、類的命名空間class_dic,類的命名空間是執行類體**而得到的

呼叫type時會依次傳入以上三個引數

綜上,class關鍵字幫我們建立乙個類應該細分為以下四個過程

補充:exec的用法

乙個類沒有宣告自己的元類,預設他的元類就是type,除了使用內建元類type,我們也可以通過繼承type來自定義元類,然後使用metaclass關鍵字引數為乙個類指定元類

class mymeta(type): #

只有繼承了type類才能稱之為乙個元類,否則就是乙個普通的自定義類

pass

class oldboyteacher(object,metaclass=mymeta): #

oldboyteacher=mymeta('oldboyteacher',(object,),)

school='

oldboy

'def

__init__

(self,name,age):

self.name=name

self.age=age

defsay(self):

print('

%s says welcome to the oldboy to learn python

' %self.name)

自定義元類可以控制類的產生過程,類的產生過程其實就是元類的呼叫過程。即oldboyteacher=mymeta('oldboyteacher',(object,),),

呼叫mymeta會先產生乙個空物件oldoyteacher,然後連同呼叫mymeta括號內的引數一同傳給mymeta下的__init__方法,完成初始化,於是我們可以

class mymeta(type): #

只有繼承了type類才能稱之為乙個元類,否則就是乙個普通的自定義類

def__init__

(self,class_name,class_bases,class_dic):

#print(self) #

#print(class_bases) #(,)

#print(class_dic) #

super(mymeta, self).__init__(class_name, class_bases, class_dic) #

重用父類的功能

ifclass_name.islower():

raise typeerror('

類名%s請修改為駝峰體

' %class_name)

if'__doc__

'not

in class_dic or len(class_dic['

__doc__

'].strip('

\n')) ==0:

raise typeerror('

類中必須有文件注釋,並且文件注釋不能為空')

class oldboyteacher(object,metaclass=mymeta): #

oldboyteacher=mymeta('oldboyteacher',(object),)

"""類oldboyteacher的文件注釋

"""school='

oldboy

'def

__init__

(self,name,age):

self.name=name

self.age=age

defsay(self):

print('

%s says welcome to the oldboy to learn python

' %self.name)

執行過程演示:儲備知識:__call__

class

foo:

def__call__(self, *args, **kwargs):

print

(self)

print

(args)

print

(kwargs)

obj=foo()

#1、要想讓obj這個物件變成乙個可呼叫的物件,需要在該物件的類中定義乙個方法__call__方法,該方法會在呼叫物件時自動觸發

#2、呼叫obj的返回值就是__call__方法的返回值

res=obj(1,2,3,x=1,y=2)

python高階 元類

1.1 什麼是元類 元類就是用來建立類的 東西 python中類也是一種物件 定義乙個類 python直譯器在執行的時候會建立乙個物件 class ai object pass print type ai 1.2 使用type建立類 type可以動態的建立類 type 類名,由父類名組成的元組,屬性...

Python高階之 元類

幾個魔術方法 new init call new 物件的建立,是乙個靜態方法,第乙個引數是cls 想想也是,不可能是self,物件還沒建立,哪來的self init 物件的初始化,是乙個例項方法,第乙個引數是self call 物件可call,注意不是類,是物件。class bar object d...

Python高階程式設計 元類程式設計

class people def init self,name self.name name property defname self return self.name name.setter defname self,value self.name value getattr 是在找不到屬性的時...