周末茶话会第一周---Python的with语法

周日茶话会开始更新啦!

亲爱的小伙伴们,大家好,我们的周末茶话会开始更新啦!

茶话会目前主要分为两个模块

  • 编程小白大战Python
  • 小苏的Python进阶之路

周日茶话会的创作目的

我们的“茶话会”是每周日在实验室进行的,一开始的目的是大家通过每周固定的一个时间,一起交流自己的编程学习心得,从而达到相互督促,共同进步的目的。后来在实践中发现,每次交流的内容没有一个记录实在是很可惜,于是我决定每次讨论结束后,将大家讨论的内容记录下来,同时将每次讨论中遇到的问题在推文中描述清楚,记录大家的学习轨迹,便于大家的后续复习。

学习笔记有什么好看的呢?

既然将讨论的内容决定以一系列推文的形式写出来,就意味着我们的《周日茶话会》系列将不仅仅是单纯的笔记记录,而是对每次讨论涉及到的知识点进行整合、梳理、深化。
在“编程小白大战Python”中,我们将从最基础的Python概念出发,对每一个语法点,每一个语法糖做深入的剖析,而不是简单的介绍基础的语法概念。“入门”是起点,但远远不是我们推文的终点。在“小苏的Python进阶之路”中,我们将记录小苏后端学习的进程,一起搞清楚Web开发中遇到的每一个知识点。
所以无论你是刚刚学习Python编程的新手,还是有其他编程语言经验,相信这一系列的推文总是有你感兴趣的内容哒~

进入正题---Python中的上下文管理器

没有上下文管理器的场景

首先我们看看在没有上下文管理器的语言中,我们要打开一个资源要进行的工作,我们以打开一个文件为例。


file = open('a.txt', 'r')
....do something....
file.close()

我们对文件、数据库连接等进行操作时,一定要记得手动释放资源,防止出现问题。可是这样一来很繁琐,也容易忘记。在上面的例子中,还隐藏着一个小小的缺陷,如果在文件操作的过程中发生了异常,很可能导致后面的file.close()不会被执行,这样将导致资源不能被及时释放。当然,我们可以使用try-finally的语句来实现:


file = open('a.txt', 'r')
try:
    ....do something....
finally:
    flie.close()

这样可以保障即使发生异常,也可以清理掉占用的资源。但是这样的写法问题在于,当我们对文件的操作(do something) 很多,而且程序中频繁出现对文件资源的访问时,程序就会变得很臃肿丑陋。为了解决这个问题,Python为我们提供了with的语法糖。

With上下文管理器

下面我们来看看用Python语法糖实现的效果


with open('a.txt', 'r') as f:
    ....do something....

借助Python提供给我们的语法糖,我们可以优雅的实现资源的管理,不用去手动回收资源。下面,我们对with语法糖做一个深入的介绍。

Python上下文管理器中的核心概念

  • 上下文管理器: 实现了上下文协议的类被称为上下文管理器

  • 上下文协议: 指明类要实现__enter()____exit()__方法

  • __enter()__: 本方法在with语句开始时被Python的解释器调用,可以(非必须)向with语句返回一个值

  • __exit()__: 本方法在with语句结束时被Python的解释器调用,可以在其中编写资源清理相关的操作

通过上面的几个概念,再结合上面的实例,我们来讲解一下我们用with语法打开文件时的过程:

  1. 首先,Python首先进入Open类中的init方法来对对象进行必要的初始化操作

  2. 然后,进入__enter()__方法中,完成所有的创建工作,并返回一个file的实例,在with语法中被我们命名为f。

  3. 最后,在对文件的操作结束后,进入__exit__()方法中进行文件的清理工作。

因为Python的封装隐藏了一些细节,我们可能对open()是不是一个类心存疑虑,这里我也没能通过调试进入到open()的内部中查看源码,所以我们接下来通过将自己定义的类实现上下文协议来验证我们的知识。

手动实现上下文管理器


class OurImplement:
    def __init__(self):
        print("Now we are in the __init__")

    def __enter__(self):
        print('Now we are in the enter')
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        print('Now we are in exit')

    def show(self):
        print('do something')


with OurImplement() as f:
    f.show()

在上面的代码中,我们在enter方法里将实例化的变量返回,并通过调用f.show()来进行验证。
结果如下:


Now we are in the __init__
Now we are in the enter
do something
Now we are in exit

从执行的结果我们可以看到,我们首先执行了我们自己定义类的构造函数,在构造函数结束后,就进入了with 语法糖中的__enter__()方法,f实际上是我们在enter函数中的返回值(这个值也可以返回数值等,不是必须返回对象,甚至可以选择不返回值,这里大家可以自行验证)。当我们对资源的操作结束后,就进入__exit__()函数完成资源清理的相关操作。

小结

本期是茶话会的第一期,主要对Python中的上下文管理器做了一些简单的讨论。可以看到,虽然都说Python语言很简单,但是其实简单的背后是通过层层的封装和优雅的设计隐藏了底层的复杂细节。在编写一般的业务逻辑代码时,可能大多数时候不需要了解这些语言的机制,但是一旦涉及到阅读源码或者是需要自己对框架进行订制,甚至是开发属于自己的框架时,这些知识就不可或缺了。本期只是对上下文管理器的一个简单浅析,下期将结合yield语法以及Python的装饰器,讲解Python contexlib中提供的 contexmanager装饰器。

今天的内容就到这里大家再见ヾ( ̄▽ ̄)ByeBye~

关于更新时间

目前计划的更新时间是每周一篇,但是考虑到期末复习呀,大创项目呀等一系列问题,拖更可能还是难以避免的吧...手动伤心T_T

题外话

其实这次已经是我第二次开始准备写作了,第一次是在CSDN上尝试写博客,写了一篇发现耗费了巨大的时间,没多久就放弃了。可是后来发现,持续的写作确实是提升自己最好的手段,一个知识点看过,学过,甚至上手实践过,都不一定能对其完完全全掌握,而如果能给别人明明白白的讲清楚,给别人讲懂,或者写一篇文章能让人看懂,在这个过程中花费的精力和心血都不会白费,会让自己以前没有关注到的点更加扎实,与其说是讲给别人听,不如说是在完善自己的知识体系。这次也一定要吸取上一次失败的教训,上一次的写作中,总担心这里的图画的不够美观,那里的排版不太合格,结果让输出无关的事情耗费了很多的时间,得不偿失。

The best is the enemy of the good.

这一次,用行动代替完美的筹划。
PS:你们的灵魂画师即将上线

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,504评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,434评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,089评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,378评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,472评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,506评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,519评论 3 413
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,292评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,738评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,022评论 2 329
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,194评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,873评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,536评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,162评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,413评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,075评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,080评论 2 352

推荐阅读更多精彩内容