• python3 之metaclass


    如果希望创建某一批类全部具有某种特征,则可通过 metaclass 来实现。使用 metaclass 可以在创建类时动态修改类定义。

    为了使用 metaclass 动态修改类定义,程序需要先定义 metaclass, metaclass 应该继承 type 类,并重写 __new__() 方法。

    下面程序定义了一个 metaclass 类:

    #定义ItemMetaClass,继承type
    class ItemMetaClass(type):
        # cls 代表动态修改的类
        # name 代表动态修改的类名
        # bases 代表被动态修改的类的所有父类
        # attrs 代表被动态修改的类的所有属性、方法组成的字典
    
        def __new__(cls, name, bases, attrs):
            #动态为该类添加一个cal_price方法
            attrs['cal_price'] = lambda self:self.price * self._discount
            return type.__new__(cls, name, bases, attrs)
    

    上面程序定义了一个 ItemMetaClass 类,该类继承了 type 类,并重写了 __new__ 方法,在重写该方法时为目标类动态添加了一个 cal_price 方法。

    metaclass 类的 __new__ 方法的作用是:当程序使用 class 定义新类时,如果指定了 metaclass,那么 metaclass 的 __new__ 方法就会被自动执行。

    例如,如下程序使用 metaclass 定义了两个类:

    #定义book类
    class Book(metaclass=ItemMetaClass):
        __slots__ = ('name', 'price', '_discount')
        def __init__(self, name, price):
            self.name = name
            self.price = price
    
        @property
        def discount(self):
            return self._discount
    
        @discount.setter
        def discount(self, discount):
            self._discount = discount
    
    
    #定义cellPhone类
    class CellPhone(metaclass=ItemMetaClass):
        __slots__ = ('price', '_discount')
        def __init__(self, price):
            self.price = price
    
        @property
        def discount(self):
            return self._discount
    
        @discount.setter
        def discount(self, discount):
            self._discount = discount
    

      

    上面程序定义了 Book 和 CellPhone 两个类,在定义这两个类时都指定了 metaclass 信息,因此当 Python 解释器在创建这两个类时,ItemMetaClass 的 __new__ 方法就会被调用,用于修改这两个类。

    ItemMetaClass 类的 __new__ 方法会为目标类动态添加 cal_price 方法,因此,虽然在定义 Book、CellPhone 类时没有定义 cal_price() 方法,但这两个类依然有 cal_price() 方法。如下程序测试了 Book、CellPhone 两个类的 cal_price() 方法: 

    #Book类实例化
    b = Book('Python基础教程', 89)
    b.discount = 0.8
    #Book类的cal_price()方法
    print(b.cal_price())
    
    #CellPhone类实例化
    cp = CellPhone(2300)
    cp.discount = 0.85
    #CellPhone类的cel_price方法
    print(cp.cal_price())
    

      

    输出结果如下:

    71.2
    1955.0
    

      

      

  • 相关阅读:
    移动web开发视口viewport
    五层网络模型
    移动web开发理解设备像素、CSS像素、DPR
    git rebase简单使用
    position:fixed; IE6下解决办法。。
    (经典收藏)三十款最常用css选择器解析
    js控制搜索内容为空则搜索按钮不能用
    SAPBOE Universe 设计方法
    【转帖】开源BI系统分类
    【转贴】SQL2005 四个排名函数(row_number、rank、dense_rank和ntile)的比较
  • 原文地址:https://www.cnblogs.com/yjt1993/p/11103368.html
Copyright © 2020-2023  润新知