class test:
a = 1
b = 2
c = 3
class TestMetaclass(type):
def __new__(cls,name,bases,attrs):
print(attrs)
attr_names = [ (attr_name.upper(),value) for attr_name,value in attrs.items() if not attr_name.startswith('__')]
print(attr_names)
return super().__new__(cls,name,bases,attrs)
class Test(dict,metaclass = TestMetaclass):
f1 = 1
f2 = 2
sS = 3
=====================我是分隔线========================
class User(Model):
# 定义类的属性到列的映射:
id = IntegerField('id')
name = StringField('username')
email = StringField('email')
password = StringField('password')
# 创建一个实例:
u = User(id=12345, name='Michael', email='[email protected]', password='my-pwd')
# 保存到数据库:
u.save()
class Field(object):
def __init__(self, name, column_type):
self.name = name
self.column_type = column_type
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__(cls,name,bases,attrs):
if(name == 'Model'):#如果是Model类的话,就不需要做任何修改
return super().__new__(cls,name,bases,attrs)
mappings = dict()#创建一个映射字典,用来存储当前创建的类的属性
for k,v in attrs.items():#遍历所有属性
if(isinstance(v,Field)):#注意k都是str,v才可能是Filed类型.用户定义的用来描述表的属性,需要修改.其他的属性不要乱动
print('Found mapping: %s ==> %s' % (k,v ))
mappings[k] = v#把这个属性添加到mappings里面,同时删除attrs里面的属性,防止实例属性和类属性冲突
for k in mappings.keys():
attrs.pop(k)
attrs['__mappings__'] = mappings#为attrs添加mappings这个属性,就是把所有自定义的属性都收集到attrs[__mapppings__]
attrs['__table__'] = name#添加表的名字,这里偷个懒,表的名字就是类的名字
return super().__new__(cls,name,bases,attrs)
class Model(dict,metaclass = ModelMetaclass):
def __init__(self, **kw):
super(Model, self).__init__(**kw)
def __getattr__(self, key):#目的是让dict的keyerror变成attributeerror,因为使用getattr时处理的是AttributeError
try:
return self[key]
except KeyError:
raise AttributeError(r"'Model' object has no attribute '%s'" % key)
def __setattr__(self, key, value):
self[key] = value
def save(self):
fields = []#fields用来存储属性的名字
params = []#params用来
args = []#args用来
for k,v in self.__mappings__.items():
fields.append(v.name)
params.append('?')#添加占位符
args.append(getattr(self,k,None))#将实例属性的值添加到args里面
sql = 'inser into %s (%s) value (%s)'%(self.__table__,','.join(fields),','.join(params))
print('SQL %s'%sql)
print('ARGS %s'%str(args))