# -*- 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__(cls, name, bases, attrs): #这个第一个判断语句的作用是什么?当创建一个类的名字为Model的时候,直接返回该类吗?没有特定的有效的作用? # print("cls.__name__",cls.__name__)#注意,这个cls指的是这个ModelMetaclass自己 print("cls=>",cls.__name__) print("attrs:",attrs)#注意,这个attrs仅仅返回自己的属性或者方法,其中是不包含父类的。 if name == 'Model': return type.__new__(cls, 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__(cls, 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='[email protected]',password='hscxrzs1st') u.save() u=User(id=2,name='Mrs.Li',email='[email protected]',password='hscxrzs1st') u.save()
关于python中的元类
猜你喜欢
转载自blog.csdn.net/hsc_1/article/details/80372672
今日推荐
周排行