日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

十九、Python MetaClass元類詳解

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

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

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

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


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

  2. class ItemMetaClass(type):

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

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

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

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

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

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

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

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

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

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

例如,如下程序使用元類定義了兩個類:
  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 兩個類,在定義這兩個類時都指定了元類信息,因此當(dāng) Python 解釋器在創(chuàng)建這兩個類時,ItemMetaClass 的 __new__ 方法就會被調(diào)用,用于修改這兩個類。

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

  2. b.discount = 0.76

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

  4. print(b.cal_price())

  5. cp = CellPhone(2399)

  6. cp.discount = 0.85

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

  8. print(cp.cal_price())

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

67.64
2039.1499999999999

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

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

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多