Python 编写ORM时的重难点掌握

前言:

       最近才狠下心来 准备做一个自己的博客 原先FuckBlog项目由于后端小伙伴加班而搁置,因此 作为团队PM的我自己也要开始做技术方面了,准备自己先写一个博客看看。

      备注- ORM全称:object related mapping  对象关系映射

0x00 为什么需要写一个ORM

首先,我觉得数据库操作不封装是很傻比的。原来我写了一个数据库导入工具,全篇导出都是sql语句 什么增删改查都他妈齐活的在各个py里面跑来跑去。给大家上一张图:

大家体会到这种乱跑的辛酸了么 从那次失败的架构我就说:再不用orm我他妈就是一傻逼

其次就是不安全,我这里再给大家举一个反例 使我们FuckBlog项目里面 后端小伙伴采用了一个异常简单的后台模板 我在查看代码的时候 发现了问题 我们看用户验证的代码:

看到了么 传输的用户名密码 居然是直接放进sql语句拼接的。大家知道怎么构造 password来达到我们想要的任意用户名都可以登录的效果了么 有几个月了 我简单说一下思路 首先引号闭合 闭合之后 然后在+ or +构造万能查询语句  只要能查询成功,就到让session进行赋值。

最后呢 就是在web中 因为:

一处异步调用 处处异步调用  

我们在查询数据库中肯定不能因为数据量过大而放弃其他的请求 这样效率非常慢所以这方面的控制 以及上文所述的问题 需要我们去封装 而方便我们的调用和请求。因此我们需要自己写一个orm工具类 去完成异步的增删改查

 

0x01 ORM 编写的一些难点

 

我跟着廖雪峰大神的博客 来学习 期间也看了不少人的跑通代码 自己的疑问点期初看的时候也很多当然 自己慢慢一点一点啃 啃几天就会发现豁然开朗。

代码加上测试一共三百多行,非常简洁,当然我估计注释就能占到八九十行,包括别人的也包括自己第一篇学习的困惑和不了解。也算是比较实用吧。 我先贴我第一版学习跑通的代码 然后呢 我会慢慢在后面进行阐述。

 

NO1: 为何要使用asyncore 和 aiomysql 这两个库

假设我们调用数据库的请求不知一个,比如用户小王访问我们网站,获取你以前的文章,那么东北社会你关哥也在同一时间访问我们网站,而文章比较多,小王的请求需要5秒才能返回结果。采用同步的话,那社会你关哥 就要等着小王请求王城才能进行请求(获得服务器关注)么? 显然不行,因此需要采用异步的收发请求 。而Python 中实现这个的就是asyncore 他封装了HTTP UDP SSL 的异步协议 可以让单线程 也可以异步收发请求。(如果你想自己实现套字节的异步收发返回,可以小小参考一下我的这篇网络脚本编写

那aiohttp是什么鬼 aiomysql 又是什么叼东西。他们都是基于asyncore 实现的异步http库 异步mysql 库 调用他们就可以实现异步请求在http 和 mysql 上。记住:一处异步 处处异步

 

NO2:关于日志的记录

引用日志模块logging 没有什么好说的 需要注意的是 在我们编写服务端的时候 良好的日志记录习惯很重要 不要被pycharm惯坏了 动不动print大法 debug大法 另外我想补充的是:logging这个吊玩儿,在多线程记录的时候会出错,需要改写其中的某些方法,别问我是如何知道的。对了,

level=logging.INFO

这个INFO大写。

 

NO3:*args **kw是什么东西?

*args 和 **kwargs 主要用于函数定义。 **kw就是**kwargs的缩写,可以传递数量不一的变量,他们的核心是前面的星号 一颗星和两颗星 而不是后面的args 你写成*fuckyou 都没事。只不过是约定俗称而已。那么这个屌丝东西怎么用呢?我们看一段示例代码:(我改自gitbook Python进阶

输出结果:

我们再来看**kwargs

**kwargs :该参数允许你将不定长度的键值对, 作为参数传递给一个函数。 如果你想要在一个函数里处理带名字的参数, 你应该使用**kwargs

你肯定回想 啥叫键值对 带名字的参数又是什么鬼 我们来看这个例子:

 

怎么样现在传的时候是不是有点小明白 就像传递一个字典一样,比如这样:

主要传进去my_info 是一个字典就好了。

一般来讲传递的顺序是 var *args **kwargs

这里面就顺便提一下,字典的get方法用法是get(key,value) 如果没有key对应的键值 则返回设定value

比如

返回就是:

email ==> [email protected]
[email protected]
Fuck None
name ==> sly
sly
Fuck None

 

NO3: yield 和 yield from 语法

 

我们都知道yield 或者说对yield 比较熟悉 因为我们教学的案例常常就是 yield result 当一个 生成器(英文:generator)。但是我们为了弄清楚这一系列的东西 我们需要首先弄清楚迭代器 生成器这些鬼东西。在这方面 除了官方文档 我还查阅了 这个 这个还有这个 当然 IBM的也不错 等等 我就不一一列出了。

生成器的简析:

我们为啥需要生成器?假设我们需要处理草榴的所有用户信息,如果一次性就处理1000万的用户信息列表非常耗费内存,我们的本地电脑内存不够用,那么就需要一个分批处理草榴用户信息生成器的东西,当我们调用一次的时候返回1000用户信息列表即可 ,下一次调用就返回uid在1001-2000的用户就好了。但是你可能会问:函数里面的return咋知道你是下一次调用还是第三次第四次调用 给你返回你想要的值呢?而这就是yield 存在的神奇方法,它能够记住。

而正因为yield 存在才使得我们不需要拥有存储 1000万草榴用户信息列表,就能逐步得到这些信息。内存占用极小。

那么可能会有人问:适用于生成器的对象自身需要可迭代能力么 也就是说我必须要是一个字典列表啥的才行么?

事实上生成器调用的对象自身必须拥有可迭代能力,之所以你认为传递列表或者字典是你把迭代在Python里面的识别狭义化了。

什么是可迭代?什么东西可以记住当前调用位置?

可迭代是指一种可以在容器中逐个提取元素的能力。

(容器:将多个元素组合在一起的数据结构,常见的容器有 dict list tuple str 文本流 以及他们这些的变形比如OrderedDict)

迭代器的内部状态可以记住当前调用位置

Python是如何识别一个对象拥有可迭代能力?

一个可迭代对象必须具备:

  • __iter__()

(为啥该命名方法前后有__因为这是Python特殊方法,以示区分,在OOP编程的后续会给大家讲到)

迭代器呢则必须具备以下特殊方法:2.x是next()

  • __iter__()
  • __next__()

我们来看廖雪峰在IBM workplace上给的yield 斐波拉切数列案例

你最终会发现这个yield 让返回的对象变成了 generator 一个生成器。 它让你关注的点更多的在算法实现上,而非存储上面。

那么我们该如何自己去实现这个迭代器呢?

调用和拥有yield 的函数一样,同上。

如果还有疑问或者我的描述有错误的可以在博客评论中提出(mail写好我回复你会收到邮件~)

解释了yield 我们来看一下 yield from 

关于yield from 这个Python 3.3 才支持的东西我们看一下:

首先,yield from 是为了解决什么问题而出现的。

看到上文我们发现一个问题,yield 不能脱离代码单独出来用,在一个生成器中调用另外一个生成器想要用,咋办 那么我们就需要yield from

yield from的的历史可以参考 这个PEP

总之大意是原本的yield语句只能将CPU控制权还给直接调用者,当你想要将一个generator或者coroutine里带有yield语句的逻辑重构到另一个generator(原文是subgenerator)里的时候,会非常麻烦,因为外面的generator要负责为里面的generator做消息传递;所以某人有个想法是让python把消息传递封装起来,使其对程序猿透明,于是就有了yield from

 

对于简单的迭代器,yield from iterable本质上等于for item in iterable: yield item的缩写版 yield from允许子生成器直接从调用者接收其发送的信息或者抛出调用时遇到的异常,并且返回给委派生产器一个值

 

那么在本次学习orm的过程中你就把他理解为异步执行即可 先别管原理了。

如果大家仍旧很感兴趣 可以参考这篇文章 我能力有限 就不画蛇添足了。

 

 

NO4. __pool 和这个__init__ 这些东西是啥?

这个就简单说一下 前面一条杠 就是非公开变量 两条杠私有变量 一条杠能调用 两条杠就不允许外部调用。不像Java 那样有什么private 什么的 别再和我说不能阻止外部调用很不安全 私有变量 不可以 You are Adult.

__str__ __init__ __name__ 这些都是特殊方法(或者魔术方法) 内置的 详细干嘛自己去Python官网看。

 

NO5.  @asyncore.coroutine 是什么鬼?

它能够将一个生成器generator标记为coroutine类型,然后扔进Eventloop 异步执行。

这里我们需要回去复习廖雪峰大神关于asyncore的讲解。(这告诉我们 翘课早晚是要还的 不管你是网课还是自学)

相关文章
相关标签/搜索