# -*- coding: utf-8 -*-
class Field(object):
#初始化两个参数,要给为name(存储的名字吗?),另一个为column_type(存储的类型吗?)
def __init__(self, name, column_type):
self.name = name
self.column_type = column_type
#print的对象,返回的是<类名:存储类型的名字>
def __str__(self):
return '<%s:%s>' % (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__(mcs, name, bases, attrs):
#这个第一个判断语句的作用是什么?当创建一个类的名字为Model的时候,直接返回该类吗?没有特定的有效的作用?
# print("mcs.__name__",mcs.__name__)#注意,这个cls指的是这个ModelMetaclass自己
print("mcs=>",mcs.__name__)
print("attrs:",attrs)#注意,这个attrs仅仅返回自己的属性或者方法,其中是不包含父类的。
if name == 'Model':
return type.__new__(mcs, name, bases, attrs)
#打印创建类的类名
print('Found model: %s' % name)
#创建一个字典mappings,用来存储属性属于
mappings = dict()
#遍历所有初始化的时候传入的属性?
for k, v in attrs.items():
#如果传入的键值对中,有的值是为Field的实例,例如Field,StringField,IntegerField,那么将其添加到mappings字典中去
if isinstance(v, Field):
print('Found mapping: %s ==> %s' % (k, v))
mappings[k] = v
#对于值属于Field的键值对,从attrs中删除
for k in mappings.keys():
attrs.pop(k)
attrs['__mappings__'] = mappings # 保存属性和列的映射关系
attrs['__table__'] = name # 假设表名和类名一致
# print("after processed:",attrs)
return type.__new__(mcs, name, bases, attrs)
class Model(dict, metaclass=ModelMetaclass):
def __init__(self, **kwarg):
print("kwargs:",kwarg)
super(Model, self).__init__(**kwarg)
def __getattr__(self, key):
try:
return self[key]
except KeyError:
raise AttributeError("'Model' object has no attribute '%s'" % key)
def __setattr__(self, key, value):
self[key] = value
# 模拟建表操作
def save(self):
fields = []
args = []
for k, v in self.__mappings__.items():
fields.append(v.name)
args.append(getattr(self, k, None))
sql = 'insert into %s (%s) values (%s)' % (self.__table__, ','.join(fields), ','.join([str(i) for i in args]))
print('SQL: %s' % sql)
print('ARGS: %s' % str(args))
#其实最重要的一点是,这个User是继承自Model的。
#那么,这个类User也是有由ModelMetaclass创建的
#这样的话,这个User里面的id,name,email,password,属性都会由ModelMetaclass的__new__(cls,name,bases,attrs)来处理
class User(Model):
# 定义类的属性到列的映射:
id = IntegerField('id')
name = StringField('username')
email = StringField('email')
password = StringField('password')
u=User(id=1,name='Mr.Hu',email='1431793998@qq.com',password='hscxrzs1st')
u.save()
u=User(id=2,name='Mrs.Li',email='1431793998@qq.com',password='hscxrzs1st')
u.save()