zoukankan      html  css  js  c++  java
  • 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
    

      

      

  • 相关阅读:
    cuda、cudnn环境配置
    1.python的 a,b=b,a+b 和 a=b b=a+b 的区别
    例子:循环语句--打印一个菱形
    7.python基础语法--format()函数
    例子:循环语句--九九乘法表
    例子:循环语句--输入N个整数,判断最大值,最小值,和,平均值。
    例子:循环语句--素数问题
    例子:循环语句--打印一个边长为n的正方形。
    例子:循环语句--给定一个不超过5位的正整数,判断该数的位数,依次打印出个位、十位、百位、千位、万位的数字。
    6.python基础语法--循环结构
  • 原文地址:https://www.cnblogs.com/yjt1993/p/11103368.html
Copyright © 2011-2022 走看看