代码拉取完成,页面将自动刷新
# -*- coding: utf-8 -*-
"""
Created on Sat Dec 2 18:37:11 2017
@author: zy
"""
#ORM:object releational mapping 对象关系模型 就是把关系数据库的一行映射为一个对象,也就是一个类对应一个表
#首先定义一个Field类,负责保存数据库表的字段名和字段类型 也可以直接使用 Field('字段名','字段数据类型')
class Field(object):
#把一个getter方法变成属性 获取__name属性的值,获取字段名
@property
def name(self):
return self.__name
#负责把一个setter方法变成属性赋值 设置__name属性的值,设置字段名
@name.setter
def name(self,value):
self.__name = value
@property
def column__type(self):
return self.__column__type
#负责把一个setter方法变成属性赋值 设置__name属性的值,设置字段名
@column__type.setter
def column__type(self,value):
#这里应给进行数据库类型检测
self.__column__type = value
#初始化给属性赋值
def __init__(self,name,column__type):
self.__name = name #字段名属性
self.__column_type = column__type #字段类型属性
def __str__(self):
#输出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')
#编写metaclass元类
class ModelMetaclass(type):
#当前准备创建的类的对象(类型)
#类的名称
#类继承的父类集合
#类的方法和属性的集合(只是一部分)
def __new__(cls,name,bases,attrs):
print('当前准备创建的类的对象 %s'%cls)
print('类的名称为%s'%name)
#排除对Model类的修改
if name == 'Model':
return type.__new__(cls,name,bases,attrs)
print('Found Model:%s'%name)
#创建一个空的dict
mappings=dict()
#在当前类,比如User类中查找类的所有属性和方法,如果找到一个Field类型的属性,就把他保存到__mappings__的dic中
#这里是为了保存数据表所有的字段名
for k,v in attrs.items():
#print('%s == >%s'%(k,v))
if isinstance(v,Field):
#k是User类中定义的属性名称,v是属性对应的值,即Field类型的实例
print('Found mapping:%s == >%s'%(k,v))
mappings[k]=v
#同时从类的属性中删除该Field属性(防止实例的属性会遮盖类的同名属性)
for k in mappings.keys():
attrs.pop(k)
#新增两个属性 用于保存字段和数据表名
attrs['__mappings__'] = mappings #保存属性和列的映射关系
attrs['__table__'] = name #假定表明和类名一样
return type.__new__(cls,name,bases,attrs)
#基类Model 程序运行的时候,首先会调用metaclass中的__new__()方法创建该类
class Model(dict,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):
self[key] = value
def save(self):
#保存类的字段名
fields = []
#保存参数 占位符
params = []
#保存待传入的数值
args = []
#k是User类中定义的属性名称,v是属性对应的值,即Field的子类型的实例
for k,v in self.__mappings__.items():
#print('%s == >%s'%(k,v))
fields.append(v.name) #追加字段名
#追加占位符
params.append('?')
#User类中定义数据表的字段名,以及对应的属性,当用户定义class User(Model)会动态创建User类,python解释器会去查找metaclass指定的ModelMetaclass
#中的__new__()方法动态创建类,在__new__放法中首先把User类的属性保存到__mappings__的dic中,然后删除这些属性
#此时如果User的实例再去获取这些属性,得到将时初始化实例时传进来的同名属性,即传进来的数据值
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))
#定义User类 当定义该类时,Python解释器首先在当前类的定义中去找metaclass,如果没有找到,就到父类Model中查找metaclass,找到了就用
#Model中的定义的metaclass的ModelMeatclass来创建User类(通过调用__new__()方法创建)、
#程序运行的时候,首先会调用metaclass中的__new__()方法创建该类
class User(Model):
#定义类的属性到列的映射
id = IntegerField('id') #创建实例 属性对应字段名
name = StringField('username')
email = StringField('email')
password = StringField('password')
#创建一个实例
#由于User类动态创建的时候已经从属性中删除了在User类中定义的属性(metaclass中的__new__()方法中删除了),当赋值id=12345
#获取调用从父类继承过来的 __setattr__()方法,会在按照dict的方式保存新追加的数据
u = User()
u.id = 12345
u.name = '郑洋'
u.email = '975481319@qq.com'
u.password = '123456aa'
#u = User(id=12345,name='郑洋',email='975481319@qq.com',password='123456')与上面等价
#调用Save()方法 保存数据
u.save()
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。