通过元类简单的实现一个类似于django的orm
既然提到元类,那么什么是元类?
元类也就是创造类的类,在python中type就是一个元类
要实现django中的orm,首先要了解属性描述符,下面给出两个属性描述符
class Field: def __init__(self, min_lenth, max_lenth): self.min_lenth = min_lenth self.max_lenth = max_lenth if min_lenth >= max_lenth: raise ValueError("最小值应该比最大值小") class InField(Field): """数据描述符""" def __init__(self, min_lenth, max_lenth): self._value = None super(InField, self).__init__(min_lenth, max_lenth) def __get__(self, instance, owner): return self._value def __set__(self, instance, value): if isinstance(value, numbers.Integral): if self.min_lenth: if value < self.min_lenth: raise ValueError("必须大于等于最小值") if self.max_lenth: if value > self.max_lenth: raise ValueError("必须小于最大值") self._value = value else: raise ValueError("参数必须输一个int类型") def __delete__(self, instance): pass class CharField(Field): """数据描述符""" def __init__(self, min_lenth, max_lenth): self._value = None super(CharField, self).__init__(min_lenth, max_lenth) def __get__(self, instance, owner): return self._value def __set__(self, instance, value): self._value = value def __delete__(self, instance): pass
编写一个元类,这里要讲的就是,既然我们要用元类创建一个类,那么当我们创建这个类的对象的时候用__new__这个魔法函数去控制实例化,在其中注入一些属性
class BaseModel(type): """因为继承了type,那么BaseMode就是一个元类""" def __new__(cls, name, base, attr, **kwargs): """__new__魔法方法控制类的实例化""" # fields的作用是把我们属于数据描述符的字段抽取出来,最后操作数据的时候用到 fields = dict() for key, value in attr.items(): if isinstance(value, Field): fields[key] = value meta = attr.get("Meta") db_table = name.lower() if meta: data = meta.__dict__ if "db_table" in data: db_table = data.get("db_table") attr["data"] = data del attr["Meta"] attr["db_table"] = db_table attr["fields"] = fields # 养成好习惯调用父类的方法返回 return super().__new__(cls, name, base, attr, **kwargs)
创建一个model父类
# 创建这个的原因呢,是因为我们要实现类似django的orm功能,因此,这个类中我们需要写一些操作数据库的方法,这样代码看起来回更加整洁,分离性更加好 class Model(metaclass=BaseModel): def __init__(self, *args, **kwargs): for key, value in kwargs.items(): if getattr(self, key, None): setattr(self, key, value)
def save(self): fields = [] values = [] for key, value in self.fields.items(): fields.append(key) values.append(str(getattr(self, key))) sql = "insert in into {db_table}({fields}) values{values}".format(db_table=self.db_table, fields=",".join(fields), values=",".join(values)) print(sql)
创建model
class User(Model): name = CharField(max_lenth=10, min_lenth=2) height = InField(max_lenth=300, min_lenth=50) class Meta: # 指明数据库中的数据表 db_table = "用户" if __name__ == "__main__": # user = User() # user.name = "witt" # user.height = 170 user = User(name="witt", height=170) user.save()
这样就基本实现了一个orm

浙公网安备 33010602011771号