精选30+云产品,助力企业轻松上云!>>>
关键信息是Model类的父类是dict,我们在构建Model的时候传入的参数会被用来初始化一个dict。所以我们创建数据实例的时候数据的名称和数据值的映射会被存储在dict当中,所以我们在save方法当中才会从self的attr当中获取字段的值。并且我们在初始化User的时候,也必须要填写每个字段的名称,原因就在这里
代码如下:
class Field:
def __init__(self, name, column_type):
self.name = name
self.column_type = column_type
def __str__(self):
return f"<{self.__class__.__name__}:{self.name}>"
class StringField(Field):
def __init__(self, name):
super(StringField, self).__init__(name, "varchar(100)")
class IntegerField(Field):
def __init__(self, name):
super(IntegerField, self).__init__(name, "bigint")
class ModelMetaclass(type):
def __new__(cls, name, bases, attrs):
if name == "Model":
return type.__new__(cls, name, bases, attrs)
print(f"Found Model:{name}")
mappings = dict()
for k, v in attrs.items():
if isinstance(v, Field):
print(f"Found Mapping:{k} ==> {v}")
mappings[k] = v
for k in mappings.keys():
attrs.pop(k)
attrs["__mappings__"] = mappings
attrs["__tables__"] = name
return type.__new__(cls, name, bases, attrs)
class Model(dict, metaclass=ModelMetaclass):
def __init__(self, **kwargs):
super(Model, self).__init__(**kwargs)
def __getattr__(self, key):
try:
return self[key]
except KeyError:
raise AttributeError(f"'Model' object has not attrbute {key}")
def __setattr__(self, key, value):
self[key] = value
def save(self):
fields = []
params = []
args = []
for k, v in self.__mappings__.items():
fields.append(v.name)
params.append("?")
args.append(getattr(self, k, None))
class User(Model):
id = IntegerField("id")
name = StringField("name")
email = StringField("email")
password = StringField("password")
age = IntegerField("age")
u = User(id=12345, name='Michael', email='[email protected]', password="my-psd", age=1)
u["name1"] = "sdalsjdkl"
print(u)
u.save()
"""
Found Model:User
Found Mapping:id ==>
Found Mapping:name ==>
Found Mapping:email ==>
Found Mapping:password ==>
Found Mapping:age ==>
{'id': 12345, 'name': 'Michael', 'email': '[email protected]', 'password': 'my-psd', 'age': 1, 'name1': 'sdalsjdkl'}
"""