• python自定义元类metaclass,约束子类


    python自定义元类,约束子类

    """
    对象的类型称为类,类的类就称为元类。Python 中对元类实例化的结果就是“普通类”,这个过程是动态的。
    在定义类时可以指定元类来改变类的创建过程。

    你想创建某一批类全部必须实现某种方法属性,则可通过 metaclass = ModelBase 来实现。
    若在继承了type的类如:ModelBase(type),并重写 new() 方法,使用 metaclass 可以在创建类时动态修改类定义。

    new(cls,) 用来创建一个(未初始化)实例;init(self,) 则是用来初始化一个实例。
    在定义metaclass = ModelBase元类的 new 方法中,因为类实例还没有创建,所以可以更改最后生成类的各项属性:诸如名称,基类或属性,方法等。
    而在 init 中由于类已经创建完成,所以无法改变。
    """

    class ModelBase(type):
        """
        cls   代表动态修改的类
        name  字符串类型,存放新类的名字
        bases 元组(tuple)类型,指定类的基类/父类
        attrs  字典类型,存放该类的所有属性(attributes)和方法(method)
        """
    
    
        def __new__(cls, name, bases, attrs, ):
            super_new = super().__new__
            # 还确保初始化只对模型子类执行(不包括模型类本身)
            parents = [b for b in bases if isinstance(b, ModelBase)]
            if not parents:
                # 创建子类,动态添加方法
                attrs['totalpay'] = lambda self: self.price * self._discount if self.price and self._discount else None
                return super_new(cls, name, bases, attrs)
    
    
    class storeModel(metaclass=ModelBase):
        __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
    
        @property
        def run(self):
            print("七夕节给女朋友买{}一共花费{}···".format(self.name, self.totalpay()))
    
    
    # 实例化
    obj = storeModel('苹果', 1000)
    obj.discount = 0.1
    obj.run
    
    obj = storeModel('香蕉', 100000)
    obj.discount = 0.1
    obj.run
    
    # 内置函数反射方法,直接修改
    setattr(storeModel, 'price', 2000)
    obj.run
  • 相关阅读:
    python socks5 代理服务
    F# 语言参考【摘自MSDN】
    vs2003版本的程序转换为vs2008版本时出现的一些问题及解决办法
    【转】SQL to Mongo Mapping Chart
    jQuery UI Download
    jQuery UI Multiselect
    jqGrid search oper
    apache下用expires_module让浏览器缓存静态文件
    【转】谈谈浏览器的缓存过期时间
    USACO 1.1 Friday the Thirteenth
  • 原文地址:https://www.cnblogs.com/justblue/p/13562119.html
Copyright © 2020-2023  润新知