ORM是创建一个实例对象,用创建他的类名当做数据表名,用创建他的类属性对应数据表的字段,不需要在自己写复杂的sql语句,而是通过对实例对象的操作时,能让代码自动帮我们整理为对应的sql语句。

class User(父类):uid = ("uid", "int unsigned")name = ("username", "varchar(20)")password = ("password", "varchar(20)")...省略...

数据库
uid
username
password
     
     

类似下图创建一个实例对象,把数据库的数据以参数入

u = User(nid=12345, name="laowang",password="123321")

通过调用某个方法,ORM自动帮我们整理为下面代码并执行:

insert into (uid,name,password) value (12345,"laowang","123321")

从而大大简化我们的工作,减少出错率!下面是完整代码(通过metaclass可以指定我们需要继承的元类):

class Mode_type(type):def __new__(cls, name, bases, attrs)mappings = dict()for k, v in attrs.items():if isinstanse(v, tuple):mappings[k] = v# 找到新字典接收完attrs的数据后,删掉attrs里的数据for k in mappings.keys[]:attrs.pop(k)# 将之前新字典保存的数据表的信息保存在attrs中attrs["__mappings__"] = mappings# name指向新创建的实例对象名,相当于保存数据表的名称attrs["__table__"] = name    return type.__new__(cls, name, bases, attrs)class User(mateclass = Mode_type):uid = ("uid", "int unsigned")name = ("username", "varchar(20)")password = ("password", "varchar(20)")#  指定元类后,以上的类属性就不在类中,而是在__mapping__指定的字典中仓储# 类似于# __mapping__ = {#        uid :("uid", "int unsigned")#        name: ("username", "varchar(20)")#        password :("password", "varchar(20)")# }# __table__ = "User"def __init__(self, **kwargs):# 取出字典里面的值for name, value in kwargs.items():setattr(self, name, value)# 这里不能用self.name = value ,这样只会让实例对象拥有name这个属性,而不是name形参背后真正替换的属性,所以用setattrdef save()# 数据表表头字段fields = []# 数据表字段对应的数据args = []for k, v in self.__mappings__.items():field.append(v[0])args.append(getattr(self, k, None))args_temp = list()# 区分参数的类型,防止写入数据表后报错for temp in args:if isinstence(temp, int):args_temp.append(str(temp))  # 类似temp = “123456”elif isinstence(temp, str):args_temp.append("""%s""" % temp)  # 类似temp = """'123321'"""sql = "insert into %s (%s) value (%s)" % (self.__table__, ",".join(fields), ",".join(args_temp))#  下面就可以执行mysql的操作,只是说ORM,所以我只打印了这句话    print(sql)u = User(uid = 123456, name="laowang", password = "123321")
u.save()

需要注意的点:

  • Metaclass的父类:Metaclass是类的模板,所以必须从`type`类型继承:
  • 选择__new__函数作为实现"修改类"的函数
    • 函数__new__(cls, name,bases,attrs)中,"cls"类似于类中其他函数的self参数,例如__init__(self),只不过self代表创建的对象,而cls代表类本身(__init__作为实例初始化的函数,需要把实例本身作为参数传进去,这样我们才能保证被修改的是实例;同理,__new__函数需要把类本身作为参数传进去,才能保证被初始化的是当前类); name代表类的名称;bases代表当前类的父类集合;attrs代表当前类的属性,是狭义上属性和方法的集合,可以用字典dict的方式传入
    • 其实我们看下用type创建一个类就很好理解这些参数了():
      u = type('User', (object,),{uid:("uid", "int unsigned"),name :("username", "varchar(20)"),password:("password", "varchar(20)"})
    • 对__new__的定义def __new__(cls, name,bases,attrs),实际上,“new”方法在Python中是真正的构造方法(创建并返回实例),通过这个方法可以产生一个”cls”对应的实例对象所以说”new”方法一定要有返回,要把创建的实例对象返回回去。在此,我们把对类的修改放到__new__方法中,然后返回修改过后的实例对象。另外,很简单的道理,选择type.__new__函数作为return的值,是因为我们的Mode_type继承自type,因此应该返回type的__new__函数创建的对象。

转载于:https://www.cnblogs.com/lzb888/p/11145901.html

python中通过元类(TYPE)简单实现对象关系映射(ORM)相关推荐

  1. Python中的元类是什么?

    元类是什么,我们将它们用于什么? #1楼 请注意,此答案适用于2008年编写的Python 2.x,元类在3.x中略有不同. 元类是使"类"工作的秘诀. 新样式对象的默认元类称为& ...

  2. Python中的元类及元类实现的单例模式

    https://www.cnblogs.com/tkqasn/p/6524879.html 在看一些框架源代码的过程中碰到很多元类的实例,看起来很吃力很晦涩:在看python cookbook中关于元 ...

  3. python中的元类Metaclass

    python中的元类Metaclass 理解元类之前需要学习的知识 如果说让我们创建一个类,最先想到的肯定是用class创建,当我们使用class创建类的时候,python解释器自动创建这个对象,但是 ...

  4. Python中的元类

    Python中的元类 Python一切皆对象,所以类也是对象. 我们知道,对象是通过类实例化创建出来的.但我们创建类时并没有进行实例化操作,为什么类也是对象呢? 类既然是对象,类肯定是另外某个类的实例 ...

  5. [转]深刻理解Python中的元类(metaclass)

    类也是对象 在理解元类之前,你需要先掌握Python中的类.Python中类的概念借鉴于Smalltalk,这显得有些奇特.在大多数编程语言中,类就是一组用来描述如何生成一个对象的代码段.在Pytho ...

  6. Python中的元类(metaclass)

    类也是对象 在理解元类之前,你需要先掌握Python中的类.Python中类的概念借鉴于Smalltalk,这显得有些奇特.在大多数编程语言中,类就是一组用来描述如何生成一个对象的代码段.在Pytho ...

  7. 深刻理解Python中的元类(metaclass)以及元类实现单例模式

    在看一些框架源代码的过程中碰到很多元类的实例,看起来很吃力很晦涩:在看python cookbook中关于元类创建单例模式的那一节有些疑惑.因此花了几天时间研究下元类这个概念.通过学习元类,我对pyt ...

  8. 深度理解python中的元类

    本文转自:(英文版)https://stackoverflow.com/questions/100003/what-is-a-metaclass-in-python   (翻译版)   http:// ...

  9. 深入理解Python中的元类(metaclass)

    注:本文原稿来自stackoverflow,原文链接,目前已收获5k高赞. 一.类也是对象 在理解元类之前,你需要先掌握Python中的类.Python中类的概念借鉴于Smalltalk,这显得有些奇 ...

最新文章

  1. WAIC 2021 | 思谋科技刘枢:赋能制造业需要什么样的算法平台?
  2. 地区的json数据_Python 连接开放航空交通数据,轻松构建航班跟踪应用!
  3. Linux中查看信息的命令
  4. Hibernate注解之@Enumerated
  5. 开源的类似于Apache ab的压力测试命令行工具SuperBenchmarker
  6. 高级数据分析1代码_用Python进行数据分析,让你一看就会
  7. JQuery Datatables —— 自定义导出列
  8. 2021中国短视频和直播电商行业人才发展报告
  9. 测开之路五十:monggodb安装与初步使用
  10. Mac新手必备技巧-如何使用 macOS 帮助菜单?
  11. python fetchall函数_关于python中的查询数据库内容中用到的fetchone()函数和fetchall()函数(转)还有fetchmany()...
  12. Vue中 引入外部字体并使用
  13. 最实用的Windows安全加固手册
  14. 华为大数据客户端安装步骤
  15. Java:class6 继承
  16. 风口起落的背后,是6271家创业公司的消亡
  17. unpacked value/target cannot be used in assignment
  18. 想学板绘,需要练习线稿么,线稿怎么画好看点?
  19. 企业智能化转型meetup回顾|开源BI AI助力企业转型之旅三阶段
  20. 编程表达年月日分秒c语言,年月日时分秒教学反思

热门文章

  1. 每一次突破都是一种进步
  2. webservices系列(二)——JAX-WS文件上传下载
  3. [轻微]WEB服务器启用了OPTIONS方法/如何禁止DELETE,PUT,OPTIONS等协议访问应用程序/tomcat下禁用不安全的http方法...
  4. 客户端是选择Java Swing还是C# Winform
  5. img超出div width时, jQuery动态改变图片显示大小
  6. treeview右键添加新节点
  7. DES加解密时 Given final block not properly padded 的解决方案
  8. node --- 创建一个Socket客户端连接到服务器
  9. 5分钟从零构建第一个 Apache Flink 应用
  10. 脚本安装smokeping