#coding:utf-8#一、首先来定义Field类,它负责保存数据库表的字段名和字段类型:class Field: 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')#二、定义元类,控制Model对象的创建class ModelMetaclass(type): '''定义元类 定义:创建类的类 优点: 对子类操作,功能像装饰器一样可以动态定制和修改被装饰的类 缺点:得程序代码的维护变得困难 实际应用:创建API 前景: - Python中的类可以生成一个对象(类的能力)(只要使用关键词class,Python解释器在执行的时候就会创建一个对象) - 同时python的类也是一个对象 - 可以增加属性 - 赋值给一个变量 - 等 动态的创建类 MyShinyClass = type('MyShinyClass', (), {}) # 返回一个类对象 print MyShinyClass ''' def __new__(cls, name, bases, attrs): if name=='Model': return super(ModelMetaclass,cls).__new__(cls, name, bases, attrs) mappings = dict() # for k, v in attrs.iteritems(): for k, v in attrs.items(): # 保存类属性和列的映射关系到mappings字典 if isinstance(v, Field): print('Found mapping: %s==>%s' % (k, v)) mappings[k] = v # for k in mappings.iterkeys(): for k in mappings.keys(): #将类属性移除,使定义的类字段不污染User类属性,只在实例中可以访问这些key attrs.pop(k) attrs['__table__'] = name.lower() # 假设表名和为类名的小写,创建类时添加一个__table__类属性 attrs['__mappings__'] = mappings # 保存属性和列的映射关系,创建类时添加一个__mappings__类属性 return super(ModelMetaclass,cls).__new__(cls, name, bases, attrs)#三、编写Model基类class Model(dict,metaclass=ModelMetaclass): """ 定义了__metaclass__就定义了这个类的元类 类反射的四个基本函数 hasattr getattr setattr delattr 反射动态获取模块的方法名 _getattr_ _delattr_ _setattr_ """ # __metaclass__ = ModelMetaclass def __init__(self, **kw): super(Model, self).__init__(**kw) def __getattr__(self, key): try: return self[key] except KeyError: raise AttributeError(r"'Model' object has no attribute '%s'" % key) def __setattr__(self, key, value): print("开始执行 setattr -- ") # self[key] = value self.__dict__[key] = value print("已经设置了属性") def save(self): fields = [] params = [] args = [] # for k, v in self.__mappings__.iteritems(): for k, v in self.__mappings__.items(): fields.append(v.name) params.append('?') args.append(getattr(self, k, None)) sql = 'insert into %s (%s) values (%s)' % (self.__table__, ','.join(fields), ','.join(params)) print('SQL: %s' % sql) print('ARGS: %s' % str(args))#最后,我们使用定义好的ORM接口,使用起来非常的简单。class User(Model): # 定义类的属性到列的映射: id = IntegerField('id') name = StringField('username') email = StringField('email') password = StringField('password')# 创建一个实例:u = User(id=12345, name='Michael', email='test@orm.org', password='my-pwd')# 保存到数据库:u.save()#输出# Found mapping: email==><StringField:email># Found mapping: password==><StringField:password># Found mapping: id==><IntegerField:id># Found mapping: name==><StringField:username># SQL: insert into User (password,email,username,id) values (?,?,?,?)# ARGS: ['my-pwd', 'test@orm.org', 'Michael', 12345]