iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > Python >怎么使用Python元类编程实现一个简单的ORM
  • 689
分享到

怎么使用Python元类编程实现一个简单的ORM

2023-07-05 09:07:55 689人浏览 安东尼

Python 官方文档:入门教程 => 点击学习

摘要

这篇文章主要讲解了“怎么使用python元类编程实现一个简单的ORM”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“怎么使用Python元类编程实现一个简单的ORM”吧!概述什么是ORM?  

这篇文章主要讲解了“怎么使用python元类编程实现一个简单的ORM”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“怎么使用Python元类编程实现一个简单的ORM”吧!

概述

什么是ORM?   

ORM全称“Object Relational Mapping”,即对象-关系映射,就是把关系数据库的一行映射为一个对象,也就是一个类对应一个表,这样,写代码更简单,不用直接操作sql语句。

现在我们就要实现简易版ORM。 

效果

class Person(Model):    """    定义类的属性到列的映射    """    pid = IntegerField('id')    names = StringField('username')    email = StringField('email')    passWord = StringField('password') p = Person(pid=10086, names='晓明', email='10086@163.com', password='123456')p.save()

怎么使用Python元类编程实现一个简单的ORM

通过执行save()方法 动态生成sql插入语句, 是不是很神奇, 那我们现在开始解析原理吧

步骤

首先我们要定义一个 Field 类 它负责保存数据库表的字段名和字段类型:

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)

在 Field 的基础上,进一步定义各种类型的 Field,比如 StringField,IntegerField 等等:

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')

下一步,就是编写最复杂的 ModelMetaclass:

class ModelMetaclass(type):     def __new__(cls, name, bases, attrs):        if name == "Model":            return type.__new__(cls, name, bases, attrs)        mappings = dict()        print("Found class: %s" % name)        for k, v in attrs.items():            if isinstance(v, Field):                print("Found mapping: %s ==> %s" % (k, v))                mappings[k] = v        for k in mappings.keys():            attrs.pop(k)        attrs["__table__"] = name  # 表名和类名一致        attrs["__mappings__"] = mappings  # 保存属性和列的映射关系        return type.__new__(cls, name, bases, attrs)

最后就是基类  Model:

class Model(metaclass=ModelMetaclass):     def __init__(self, **kwargs):        _setattr = setattr        if kwargs:            for k, v in kwargs.items():                _setattr(self, k, v)        super(Model, self).__init__()     def save(self):        fields = []        params = []        args = []        for k, v in self.__mappings__.items():            fields.append(k)            params.append("?")            args.append(getattr(self, k, None))        sql = "insert into %s (%s) values (%s)" % (self.__table__, ','.join(fields), ",".join(params))        print('插入语句: %s' % sql)        print('参数: %s' % str(args))     def update(self):        fields = []        args = []        for k, v in self.__mappings__.items():            if getattr(self, k, None):                fields.append(k+"=?")                args.append(getattr(self, k, None))        sql = "update %s set %s" % (self.__table__, ','.join(fields))        print("更新语句: %s " % sql)        print("参数: %s" % args)     def filter(self, *args):        pass     def delete(self):        pass

当用户定义一个 class Person(Model) 继承父类时,Python解释器会在当前类 Person 的定义中找 __metaclass__,如果没有找到,就继续到父类中找 __metaclass__,实在找不到就用默认 type 类。

我们在父类 Model 中定义了 __metaclass__ 的 ModelMetaclass 来创建 Person 类,所以 metaclass 隐式地继承到子类。

在 ModelMetaclass 中,一共做了几件事情:

  • 排除掉对 Model 类的修改;

  • 在当前类(比如 Person )中查找定义的类的所有属性,如果找到一个 Field 属性,就把它保存到一个 __mappings__ 的dict中,同时从类属性中删除该Field属性,否则,容易造成运行时错误;

  • 把表名保存到 __table__ 中,这里简化为表名默认为类名。

在Model类中,就可以定义各种操作数据库的方法,比如save(),delete(),find(),update() 等等。

我们实现了save(), update()方法,把一个实例保存到数据库中。因为有表名,属性到字段的映射和属性值的集合,就可以构造出INSERT语句和UPDATE语句。

编写代码试试:

class UserInfo(Model):    """        定义类的属性到列的映射    """    uid = IntegerField('uid')    name = StringField('username')    email = StringField('email')    password = StringField('password')  class Person(Model):    """    定义类的属性到列的映射    """    pid = IntegerField('id')    names = StringField('username')    email = StringField('email')    password = StringField('password') p = Person(pid=10086, names='晓明', email='10086@163.com', password='123456')p.save()u2 = UserInfo(password='123456')u2.update()

输出

Found class: UserInfo
Found mapping: uid ==> <IntegerField:uid>
Found mapping: name ==> <StringField:username>
Found mapping: email ==> <StringField:email>
Found mapping: password ==> <StringField:password>
Found class: Person
Found mapping: pid ==> <IntegerField:id>
Found mapping: names ==> <StringField:username>
Found mapping: email ==> <StringField:email>
Found mapping: password ==> <StringField:password>
插入语句: insert into Person (pid,names,email,password) values (?,?,?,?)
参数: [10086, '晓明', '10086@163.com', '123456']
更新语句: update UserInfo set password=? 
参数: ['123456']

结束语

就这样一个小巧的ORM就这么完成了。是不是学到了很多呢 ?这里利用的是元编程,很多Python框架都运用了元编程达到动态操作类。

注:上述代码列子 结合了廖雪峰的列子和少量的Django ORM源码

完整代码

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":            return type.__new__(cls, name, bases, attrs)        mappings = dict()        print("Found class: %s" % name)        for k, v in attrs.items():            if isinstance(v, Field):                print("Found mapping: %s ==> %s" % (k, v))                mappings[k] = v        for k in mappings.keys():            attrs.pop(k)        attrs["__table__"] = name  # 表名和类名一致        attrs["__mappings__"] = mappings  # 保存属性和列的映射关系        return type.__new__(cls, name, bases, attrs)  class Model(metaclass=ModelMetaclass):     def __init__(self, **kwargs):        _setattr = setattr        if kwargs:            for k, v in kwargs.items():                _setattr(self, k, v)        super(Model, self).__init__()     def save(self):        fields = []        params = []        args = []        for k, v in self.__mappings__.items():            fields.append(k)            params.append("?")            args.append(getattr(self, k, None))        sql = "insert into %s (%s) values (%s)" % (self.__table__, ','.join(fields), ",".join(params))        print('插入语句: %s' % sql)        print('参数: %s' % str(args))     def update(self):        fields = []        args = []        for k, v in self.__mappings__.items():            if getattr(self, k, None):                fields.append(k+"=?")                args.append(getattr(self, k, None))        sql = "update %s set %s" % (self.__table__, ','.join(fields))        print("更新语句: %s " % sql)        print("参数: %s" % args)     def filter(self, *args):        pass     def delete(self):        pass  class UserInfo(Model):    """        定义类的属性到列的映射    """    uid = IntegerField('uid')    name = StringField('username')    email = StringField('email')    password = StringField('password')  class Person(Model):    """    定义类的属性到列的映射    """    pid = IntegerField('id')    names = StringField('username')    email = StringField('email')    password = StringField('password') p = Person(pid=10086, names='晓明', email='10086@163.com', password='123456')p.save()u2 = UserInfo(password='123456')u2.update()

感谢各位的阅读,以上就是“怎么使用Python元类编程实现一个简单的ORM”的内容了,经过本文的学习后,相信大家对怎么使用Python元类编程实现一个简单的ORM这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是编程网,小编将为大家推送更多相关知识点的文章,欢迎关注!

--结束END--

本文标题: 怎么使用Python元类编程实现一个简单的ORM

本文链接: https://www.lsjlt.com/news/350762.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 怎么使用Python元类编程实现一个简单的ORM
    这篇文章主要讲解了“怎么使用Python元类编程实现一个简单的ORM”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“怎么使用Python元类编程实现一个简单的ORM”吧!概述什么是ORM   ...
    99+
    2023-07-05
  • Python元类编程实现一个简单的ORM
    目录概述效果步骤结束语完整代码概述 什么是ORM    ORM全称“Object Relational Mapping”,即对象-关系映射,就是把关系数据库的...
    99+
    2023-03-06
    Python元类编程ORM Python ORM
  • 使用Python怎么实现一个ORM模型
    本篇文章为大家展示了使用Python怎么实现一个ORM模型,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。元类对于元类,我的理解其实也便较浅,大概是这个意思所有的类都是使用元类来进行创建的,而所有的类...
    99+
    2023-06-15
  • 用Python实现一个简单的线程池
    线程池的概念是什么?在面向对象编程中,创建和销毁对象是很费时间的,因为创建一个对象要获取内存资源或者其它更多资源。在Java中更是 如此,虚拟机将试图跟踪每一个对象,以便能够在对象销毁后进行垃圾回收。所以提高服务程序效率的一个手段就是尽可能...
    99+
    2023-01-31
    线程 简单 Python
  • 怎么使用Python编写一个简单的垃圾邮件分类器
    这篇文章主要介绍“怎么使用Python编写一个简单的垃圾邮件分类器”,在日常操作中,相信很多人在怎么使用Python编写一个简单的垃圾邮件分类器问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”怎么使用Pytho...
    99+
    2023-07-06
  • 用Python实现一个简单的WebSoc
    ubuntu下python2.76 windows python 2.79, chrome37 firefox35通过 代码是在别人(cddn有人提问)基础上改的, 主要改动了parsedata和sendmessage这2个函数. 改代码...
    99+
    2023-01-31
    简单 Python WebSoc
  • 使用Python怎么实现元编程
    本篇文章为大家展示了使用Python怎么实现元编程,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。一、前言首先说,Python中一切皆对象,老生常谈。还有,Python提供了许多特殊方法、元类等等这样...
    99+
    2023-06-15
  • 怎么用Python编写一个简单的游戏
    本篇内容介绍了“怎么用Python编写一个简单的游戏”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!在这个系列中,我们要用不同的编程语言编写相...
    99+
    2023-06-15
  • python实现一个简单的dnspod
    实现一个简单的dnspod解析api:dnspod api地址:https://www.dnspod.cn/docs/records.html#record-create #!/usr/bin/env python # -*- coding...
    99+
    2023-01-31
    简单 python dnspod
  • 怎么使用python实现一个简单的贪吃蛇游戏
    本篇内容主要讲解“怎么使用python实现一个简单的贪吃蛇游戏”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“怎么使用python实现一个简单的贪吃蛇游戏”吧!pygame 写的“贪吃蛇”小游戏:...
    99+
    2023-07-02
  • 如何使用Python元类特性实现ORM框架
    这篇文章主要介绍了如何使用Python元类特性实现ORM框架,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。ORM是什么O是 object,也就 类对象 的意思,R是 rela...
    99+
    2023-06-15
  • 用Python实现一个简单的抽奖小程序
    目录写在前面 实现结果 1 数据拉取2 数据清洗、去重3 中奖数据抽取python 相关知识点总结写在前面  因为粉丝福利,所以想自己写一个抽...
    99+
    2023-05-12
    python抽奖系统 python随机抽奖 python抽奖游戏
  • 使用Python实现一个简单的接口服务
    使用Python实现一个简单的接口服务,可以通过get、post方法请求该接口,拿到响应数据。创建一个api_server.py文件,添加代码如下: import flask, json from flask import reques...
    99+
    2023-01-31
    接口 简单 Python
  • 怎么使用Python写一个简单的JSONParser
    JSON TokenizerJSON 的词法分析,我主要是参考上面这个截图里面的方式,自己写了一个简单的示例。写得比较简单,应该说它只能支持 JSON 的一个简单子集。这里 TOKEN 的种类,参考了 https://json.org,不过...
    99+
    2023-05-14
    Python
  • C++怎么实现一个简单的线程池
    本文小编为大家详细介绍“C++怎么实现一个简单的线程池”,内容详细,步骤清晰,细节处理妥当,希望这篇“C++怎么实现一个简单的线程池”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。一、设计线程池应该包括保存线程的容...
    99+
    2023-06-30
  • 怎么使用JavaScript实现一个简单的通讯录
    这篇文章主要介绍“怎么使用JavaScript实现一个简单的通讯录”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“怎么使用JavaScript实现一个简单的通讯录”文章能帮助大家解决问题。创建通讯录对...
    99+
    2023-07-06
  • 使用c# 怎么编写一个ORM框架
    今天就跟大家聊聊有关使用c# 怎么编写一个ORM框架,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。1. ORMORM全称 Object Relational Mapping,翻译过来...
    99+
    2023-06-14
  • 用Python编写一个简单的Http S
    原文地址:Write a simple HTTP server in Python http://www.acmesystems.it/python_httpd 例子中源码: https://github.com/tanzi...
    99+
    2023-01-31
    简单 Python Http
  • 如何实现一个最简单的vbs类
    这篇文章主要介绍如何实现一个最简单的vbs类,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!class CFoo     sub PrintHell...
    99+
    2023-06-08
  • 用Python实现一个简单的用户系统
    目录前言正文总结前言  如标题所说,这是一个非常简单的程序,并不涉及任何高深的学问,更适合一些刚入手Python的新人研究一下基础内容的用法,此案列对于有些编程经验的人来讲...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作