初步認識元類python
#本篇文章介紹的元類,以及type以python3以上版本爲準。python2.7
一.關於元類的前言。
ide
在python中,一切皆對象,固然,類也是一個對象。
函數
class c1:spa
passorm
obj1 = c1()對象
從上面這段例子能夠看到,obj1是c1這個類建立出來的一個對象,obj1是由c1去產生的,若是按照前面的理論來理解,類也是一個對象,那麼c1是由誰建立出來的呢?繼承
#type函數能夠查看類型,也能夠用來查看對象的類,兩者是同樣的內存
print(type(obj1)) # 輸出:<class '__main__.c1'> 表示,obj1 對象由c1類建立it
print(type(c1)) # 輸出:<type 'type'>
也就是說咱們定義的類,所有都是由type產生的。
經過這個知識點,能夠引出兩種建立類的方式。
方式一:使用class關鍵字定義一個類。
class Foo:
def func(self):
print('from func')
方式二:經過type定義一個類。
def func(self):
print('from func')
x=1
Foo=type('Foo',(object,),{'func':func,'x':1})
二.什麼是元類?
所謂的元類,能夠理解爲它是類的類,元類是去控制如何建立一個類的,就像類是對象的模版同樣,元類則是類的模版。
type和元類由什麼關係呢?
當一個類沒有聲明本身的元類時,這個類默認的元類就是type。
不止如此,用戶還能夠經過type來定義一個元類。
注意!當自定義元類的時候,本身定義的元類必定要繼承type!
關於元類參數的剖析:
python2.7ver:
class mytype(type):
def __init__(self,class_name,bases,dict):
print "mytype __init__ runing!!"
print class_name #類的名字
print bases #繼承的父類
print dict #類的名稱空間字典(也就是類的__dict__)
print self #定義的類的本體(也就是類的內存地址)
class test_class(object): #將mytype做爲元類,建立一個類,名爲test_class
__metaclass__ = mytype #python2.7中指定元類的方法。
def running(self):
print "runing....."
接下來執行如下代碼。
輸出:
mytype __init__ runing!!
test_class
(<type 'object'>,)
{'__module__': 'test1', '__metaclass__': <class 'test1.mytype'>, 'running': <function running at 0x10e149c08>}
<class 'test1.test_class'>
python3.5ver:
class mytype(type):
def __init__(self,class_name,bases,dict):
print("mytype __init__ runing!!")
print(class_name) #類的名字
print(bases) #繼承的父類
print(dict) #類的名稱空間字典(也就是類的__dict__)
print(self) #定義的類的本體(也就是類的內存地址)
class test_class(metaclass = "mytype"): #將mytype做爲元類,建立一個類,名爲test_class
def running(self):
print("runing.....")
#從輸出的結果能夠看出,當咱們在建立一個類的時候,就會觸發元類的__init__構造方法,就好像是用類建立對象的過程同樣。
類是如何實例化出屬性的呢?下面就經過元類手動來實現這個功能。
python2.7ver:
class mytype(type):
def __init__(self,class_name,bases,dict):
print "mytype __init__ runing!!"
print class_name
print bases
print dict
print self
def __call__(self, *args, **kwargs): # 當使用類去實例化一個對象的時候,類後面須要加()這就會觸發元類中定義的__call__方法。
print "mytype call runing -----> %s,%s,%s" %(self,args,kwargs)
obje = self.__new__(self) #生成一個空的對象
self.__init__(obje,*args,**kwargs) #調用元類所建立類的構造方法。
return obje #將空對象返回
class test_class(object):
__metaclass__ = mytype
a = 1
def running(self):
print "runing....."
obj1 = test_class()
print obj1.a