8.python之面相對象part.9(初識元類part.1)

初步認識元類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

相關文章
相關標籤/搜索