python 元类 orm_python3 通过元类实现orm

本文介绍如何使用元类(ModelMetaClass)和数据属性描述符实现简单的ORM(对象关系映射),定义了IntField和CharField,用于验证字段类型并设置范围限制。BaseModel类作为基类,统一了初始化逻辑,User模型作为示例展示继承和使用方式。
摘要由CSDN通过智能技术生成

通过元类简单实现orm

import numbers

class Field:

"""

没有属性/方法的类,用于在元类中检查传过来的变量的值,是否属于Field类型

"""

pass

class IntField(Field):

"""

数据属性描述符

用于检查整型变量的值

"""

def __init__(self, db_column, min_value=None, max_value=None):

self._value = None

self.min_value = min_value

self.max_value = max_value

self.db_column = db_column

if min_value is not None:

if not isinstance(min_value, numbers.Integral):

raise ValueError("min_value must be int")

elif min_value < 0:

raise ValueError("min_value must be positive int")

if max_value is not None:

if not isinstance(max_value, numbers.Integral):

raise ValueError("max_value must be int")

elif max_value < 0:

raise ValueError("max_value must be positive int")

if min_value is not None and max_value is not None:

if min_value > max_value:

raise ValueError("min_value must be smaller than max_value")

def __get__(self, instance, owner):

return self._value

def __set__(self, instance, value):

# 检查参数是否是int类型

if not isinstance(value, numbers.Integral):

raise ValueError("int value need")

if value < self.min_value or value > self.max_value:

raise ValueError("value must between min_value and max_value")

self._value = value

class CharField(Field):

"""

数据属性描述符

用于检查字符串变量的值

"""

def __init__(self, db_column, max_length=None):

self._value = None

self.db_column = db_column

if max_length is None:

raise ValueError("you must spcify max_lenth for charfiled")

self.max_length = max_length

def __get__(self, instance, owner):

return self._value

def __set__(self, instance, value):

if not isinstance(value, str):

raise ValueError("str value need")

if len(value) > self.max_length:

raise ValueError("value len excess len of max_length")

self._value = value

class ModelMetaClass(type):

"""

元类

在动态创建类之前,控制实例化的过程

"""

def __new__(cls, name, bases, attrs, **kwargs):

if name == "BaseModel":

return super().__new__(cls, name, bases, attrs, **kwargs)

fields = {}

for key, value in attrs.items():

if isinstance(value, Field):

fields[key] = value

attrs_meta = attrs.get("Meta", None)

_meta = {}

db_table = name.lower()

if attrs_meta is not None:

table = getattr(attrs_meta, "db_table", None)

if table is not None:

db_table = table

_meta["db_table"] = db_table

attrs["_meta"] = _meta

attrs["fields"] = fields

del attrs["Meta"]

return super().__new__(cls, name, bases, attrs, **kwargs)

class BaseModel(metaclass=ModelMetaClass):

"""在BaseModel中继承元类,其它类继承BaseModel,这样做的目地: 可以统一进行初始化及其它逻辑实现"""

def __init__(self, *args, **kwargs):

for key, value in kwargs.items():

setattr(self, key, value)

super().__init__()

def save(self):

fields = []

values = []

for key, value in self.fields.items():

db_column = value.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 {db_table}({fields}) value({values})".format(db_table=self._meta["db_table"],

fields=','.join(fields),

values=','.join(values))

# 数据库插入操作

pass

class User(BaseModel):

"""继承BaseModel 在BaseModel类里进行初始化,这样当其它类继承BaseModel时,也可省去当前类的初始化过程"""

name = CharField(db_column="name", max_length=10)

age = IntField(db_column="age", min_value=1, max_value=100)

class Meta:

db_table = "user"

if __name__ == '__main__':

user = User()

# user = User(name="aaa", age=100)

user.name = "test1"

user.age = 30

user.save()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值