小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

十九、Python MetaClass元類詳解

 星光閃亮圖書(shū)館 2019-08-08
type() 函數(shù)更適合于動(dòng)態(tài)地創(chuàng)建相對(duì)簡(jiǎn)單的類,如果要?jiǎng)?chuàng)建更復(fù)雜的類,則需要通過(guò) MetaClass(元類)的方式。

MetaClass(元類),簡(jiǎn)單的理解,就是創(chuàng)建類的類,即創(chuàng)建類之后,再由類來(lái)創(chuàng)建實(shí)例進(jìn)行應(yīng)用。使用元類可以在創(chuàng)建類時(shí)動(dòng)態(tài)修改類定義。為了使用元類動(dòng)態(tài)修改類定義,程序需要先定義元類。

定義元類時(shí),需令其繼承與 type 類,且默認(rèn)的命名習(xí)慣是,讓類名以 MetaClass 結(jié)尾。不僅如此,元類中需要定義并實(shí)現(xiàn) __new__() 方法(一定要有返回值)。因?yàn)樵愒趧?chuàng)建類時(shí),該 __new__() 方法將會(huì)被調(diào)用,用來(lái)生成新建的類。

之所有要求元類繼承 type 并實(shí)現(xiàn) __new__() 方法,是因?yàn)樵趧?chuàng)建類時(shí),內(nèi)部調(diào)用了 type 的 __new__() 方法為這個(gè)類分配內(nèi)存空間,當(dāng)內(nèi)存分配完成后,便會(huì)調(diào)用 type 的 _init__ 方法初始化。


下面程序定義了一個(gè)元類類:
  1. # 定義Item元類,繼承type

  2. class ItemMetaClass(type):

  3. # cls代表動(dòng)態(tài)修改的類

  4. # name代表動(dòng)態(tài)修改的類名

  5. # bases代表被動(dòng)態(tài)修改的類的所有父類

  6. # attr代表被動(dòng)態(tài)修改的類的所有屬性、方法組成的字典

  7. def __new__(cls, name, bases, attrs):

  8. # 動(dòng)態(tài)為該類添加一個(gè)cal_price方法

  9. attrs['cal_price'] = lambda self: self.price * self.discount

  10. return type.__new__(cls, name, bases, attrs)

上面程序定義了一個(gè) ItemMetaClass,該類繼承了 type 類,并重寫(xiě)了 __new__ 方法,在重寫(xiě)該方法時(shí)為目標(biāo)類動(dòng)態(tài)添加了一個(gè) cal_price 方法。

元類的 __new__ 方法的作用是:當(dāng)程序使用 class 定義新類時(shí),如果指定了元類,那么元類的 __new__ 方法就會(huì)被自動(dòng)執(zhí)行。

例如,如下程序使用元類定義了兩個(gè)類:
  1. # 定義Book類

  2. class Book(metaclass=ItemMetaClass):

  3.     __slots__ = ('name', 'price', '_discount')

  4.     def __init__(self, name, price):

  5.         self.name = name

  6.         self.price = price

  7.     @property

  8.     def discount(self):

  9.         return self._discount

  10.     @discount.setter

  11.     def discount(self, discount):

  12.         self._discount = discount

  13. # 定義cellPhone類

  14. class CellPhone(metaclass=ItemMetaClass):

  15.     __slots__ = ('price', '_discount' )

  16.     def __init__(self, price):

  17.         self.price = price

  18.     @property

  19.     def discount(self):

  20.         return self._discount

  21.     @discount.setter

  22.     def discount(self, discount):

  23.         self._discount = discount

上面程序定義了 Book 和 CellPhone 兩個(gè)類,在定義這兩個(gè)類時(shí)都指定了元類信息,因此當(dāng) Python 解釋器在創(chuàng)建這兩個(gè)類時(shí),ItemMetaClass 的 __new__ 方法就會(huì)被調(diào)用,用于修改這兩個(gè)類。

ItemMetaClass 類的 __new__ 方法會(huì)為目標(biāo)類動(dòng)態(tài)添加 cal_price 方法,因此,雖然在定義 Book、CellPhone 類時(shí)沒(méi)有定義 cal_price() 方法,但這兩個(gè)類依然有 cal_price() 方法。如下程序測(cè)試了 Book、CellPhone 兩個(gè)類的 cal_price() 方法: 
  1. b = Book("Python基礎(chǔ)教程", 89)

  2. b.discount = 0.76

  3. # 創(chuàng)建Book對(duì)象的cal_price()方法

  4. print(b.cal_price())

  5. cp = CellPhone(2399)

  6. cp.discount = 0.85

  7. # 創(chuàng)建CellPhone對(duì)象的cal_price()方法

  8. print(cp.cal_price())

運(yùn)行上面程序,可以看到如下運(yùn)行結(jié)果:

67.64
2039.1499999999999

從上面的運(yùn)行結(jié)果來(lái)看,通過(guò)使用元類可以動(dòng)態(tài)修改程序中的一批類,對(duì)它們集中進(jìn)行某種修改。這個(gè)功能在開(kāi)發(fā)一些基礎(chǔ)性框架時(shí)非常有用,程序可以通過(guò)使用元類為某一批需要具有通用功能的類添加方法。

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買(mǎi)等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多