python元类

type() 内置元类


# print(type('Hello'))

class Add():
    pass

# print(type(Add))  # Add 类
# print(type(Add()))  # Add()类的实例
# add = Add()
# print(type(add))    # add 实例化对象

# 利用 type() 函数动态创建一个类 ('func_name', (要继承的父类), {类的属性、类的实例属性、类的方法})
# 注意!!! (要继承的父类) 是一个元组[ 例子:(Add,) ]
print(type('Func', (), {})) 

Func1 = type('Func1', (), {'className': 'Func'})    #使用元类 type() 创建出一个对象,这个对象称为“类”
func1 = Func1() #使用“类”来创建出实例对象
print(func1.className)

自定义元类

实现 ORM(对象关系映射) 对数据库的 '增、删、改、查'

1. 使用描述器定义字段属性

# 定义字段属性的基类Field,它的用处主要用于识别类属性中属于字段的那些属性
class Field(object):
    pass

# 整型字段属性
class IntField(Field):
    def __init__(self, db_column=""):
        self._value = None # 表的数据
        self.db_column = db_column

    def __set__(self, instance, value):
        if not isinstance(value, int):
            raise ValueError("input should be a Integer")
        self._value = value

    def __get__(self, instance, owner):
        return self._value

# 字符型字段属性
class  CharField(Field):
    def __init__(self, db_column=""):
        self._value  = None 
        self.db_column = db_column

    def __get__(self, instance, owner):
        return self._value

    def __set__(self, instance, value):
        if not isinstance(value, str):
            raise ValueError("input should be a String")
        self._value = value

2. 定义元类

class MetaModel(type):
    def __new__(cls, name, bases, attrs, **kwargs):
        fields = {}
        for key, val in attrs.items():
            # 把attrs中与数据库表字段有关的列提取出来
            if isinstance(val, Field):
                fields[key] = val   # value 直接走描述器__get__()

        _meta = {}
        db_table = name.lower()  # 数据表名称默认取小写类名称
        _meta['db_table'] = db_table
        attrs['_meta'] = _meta
        attrs['_fields'] = fields

        # 以上过程相当于对类进行了修改
        return super(MetaModel, cls).__new__(cls, name, bases, attrs, **kwargs)

3. 定义模型基类

class Model(metaclass=MetaModel):
    def __init__(self, *args, **kwargs):
        for key, val in kwargs.items():
            setattr(self, key, val)
        return super(Model, self).__init__()

    def save(self):
        fields = []
        values = []
        for key, val in self._fields.items():
            db_column = val.db_column
            if db_column is None:
                db_column = key.lower()
            fields.append(db_column)
            value = getattr(self, key) # 字段的值
            values.append(str(value))
        sql = "insert {name} ({field}) values ({value})".format(name=self._meta['db_table'],field=','.join(fields),value=','.join(values))
        return sql

    def select(self):
        fields = []
        where = []
        for key, val in self._fields.items():
            db_column = val.db_column
            if db_column is None:
                db_column = key.lower()
            fields.append(db_column)
            v = getattr(self, key, None)
            if v is not None:
                where.append([key, str(v)])     # [key, str(v)] 等价于 字典的键值对
                
        # ['='.join(x) for x in where] => name=sean

        sql = 'select {fields} from {name} where {where}'.format(name=self._meta['db_table'], fields=','.join(fields),where=' and '.join(['='.join(x) for x in where]),)
        return sql

你可能感兴趣的:(python元类)