python中元類的 call

2021-08-13 03:42:18 字數 3016 閱讀 3590

元類是類的類,元類之於類就相當於類之於例項。

元類的new方法會建立乙個類並返回,就像類的new方法會建立乙個例項並返回一樣。

元類中其他方法的定義類似於類中方法的定義,例如:

class

meta

(type):

def__new__

(cls, name, bases, dct):

# cls為元類meta

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

deffoo(cls, *args, **kwargs):

# cls為元類建立的類

pass

def__call__

(cls, *args, **kwargs):

# cls為元類建立的類

pass

元類中有乙個特殊的方法__call__,這個方法會階段類的__new____init__

__call__應該返回例項,和類的__new__方法返回的一樣。

class

meta

(type):

def__new__

(cls, name, bases, dct):

print("calling meta's __new__", cls)

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

def__call__

(cls, *args, **kwargs):

print("calling meta's __call__", cls)

i = cls.__new__(cls)

i.__init__(*args, **kwargs)

return i

class

a(object):

__metaclass__ = meta

def__new__

(cls, *args, **kwargs):

print("calling a's __new__")

return object.__new__(cls)

def__init__

(self, *args, **kwargs):

print("calling a's __init__")

a = a()

print("a is", a)

執行結果
calling meta's __new__ __main__.meta'>

calling meta's __call__

calling

a's__new__

calling

a's__init__ais

<__main__.a

object

at 0x7faadaf02390>

此時,還不太能看出來meta.call攔截了a.__new__a.__init__,只能看出,__call__會先於__new____init__呼叫。(其實可以看出,如果沒有攔截發生,calling a's __new__calling a's __init__會輸出兩次)

為了更清楚的看出攔截行為,我們更改一下類的定義:

class

meta

(type):

def__new__

(cls, name, bases, dct):

print("calling meta's __new__", cls)

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

def__call__

(cls, *args, **kwargs):

print("calling meta's __call__", cls)

i = object.__new__(cls)

i.__init__(*args, **kwargs)

return i

class

a(object):

__metaclass__ = meta

def__new__

(cls, *args, **kwargs):

print("calling a's __new__")

return object.__new__(cls)

def__init__

(self, *args, **kwargs):

print("calling a's __init__")

輸出結果:
calling meta's __new__ __main__.meta'>

calling meta's __call__

calling

a's__init__ais

<__main__.a

object

at 0x7fd6b122c3d0>

可以看出,a.__new__沒有被呼叫,__call__返回的即為類的例項物件。

如果去掉__call__中的__init__呼叫,上面輸出結果中就不會出現calling a's __init__,由此可以確定,__call__攔截了__new____init__如果元類中定義了__call__,此方法必須返回乙個物件,否則類的例項化就不會起作用。(例項化得到的結果為__call__的返回值)

python元類的使用 python中元類用法例項

1.元類 metaclass 是用來建立類的類 2.type object 返回乙個物件的型別,與object.class 的值相同,type name,bases,dict 建立乙個新的type型別,name就是新class的name,值存到 name 屬性中,bases是tuple型別,值會存到...

理解Python類裝飾器 call

coding utf 8 深入理解類裝飾器 一 類裝飾器 都不帶引數 class clsdeco def init self,func self.func func def call self,args,kwargs print f running self.func print end clsde...

python類裝飾器即 call

1.類中的 call 方法 我們在定義好乙個類後,例項化出乙個物件,如果對這個物件以直接在後邊加括號的方式進行呼叫,程式就會報錯。也就是在類中這種做法是錯誤的 而,如果乙個類中寫入了 call 方法,當我問在對例項物件以括號的方式進行呼叫時,call 方法中的語句就會被執行,如下 1 import ...