元類是類的類,元類之於類就相當於類之於例項。
元類的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 ...