问题的起源

早些时候使用with实现了一版全局进程锁,希望实现以下效果:

全局进程锁本身不用多说,大部分都依靠外部的缓存来实现的,redis上用的是setnx,有时候根据需要加上缓存击穿问题、随机延后以防止对缓存本身造成压力。

当时同样写了单元测试来测试这段代码的有效性:

看起来非常完美地通过了。

这样的一个全局进程锁是通过__enter__方法抛出异常, __exit__方法中捕获异常来实现的:

看起来还不错,毕竟单元测试都过了。

但是,这样的实现是有问题的:

原因在于__exit__ 的执行不是包在__enter__ 之外的,因此__enter__抛出的异常,不会被__exit__捕获。

上面的单元测试恰好通过,是因为其中有两个with语句,外面的with 捕获的其实是里面的__enter__ 抛出的异常

使用改进后的单元测试:

就会发现单元测试过不去了。

这个问题是我试图使用with实现另一个逻辑:AB测试 时出现的,同样是__enter__抛出异常,__exit__ 试图捕获:

调试没有通过的单元测试的时候发现,抛出异常后根本没有执行到__enter__。

第一种解决方案

既然想明白了with的执行顺序,那么第一种解决方案就呼之欲出了:既然__exit__捕获的异常在__enter__执行完成之后,那么我们提供一个函数确认一下就可以了,把ABContext实现改成这样:

使用的时候:

但这样的解决方法并不优雅,万一使用这个ABContext的时候忘记用ensure方法了,那么就等于完全没用这个Context方法,太容易失误了,而且代码也失去了Pythonic的性质。

第二种解决方法

翻了一下contextlib的标准库文档,发现有一个已经废弃的函数:contextlib.nested

可以执行多个上下文:

这个废弃的特性在Python2.7之后,可以直接由with关键字执行,形如:

这个特性还不错,根据__enter__的执行顺序的话,那么我们可以实现一个由第一个 context的__exit__来捕获,第二个context的__enter__来抛出异常,

如同这样:

结合前面我们实现的ABContext的使用是这样的:

good,单元测试就这样过了!

能不能再给力点?

确实,在with里要写俩context有点蛋疼,并不是特别优雅,能不能还是回到最初的那种用法:我们只用写一条context,这一个context做到了两个context的事情?

要是nested那个函数还在就好了。。要的其实就是它的功能。

Python3.1之后contextlib提供了一个ExitStack的功能来提供一个模拟的功能,但试了一下发现,实际上只调用了__enter__方法,但没有做对应的异常捕获。

第三种解决方案

哈哈哈哈把自己绕到圈子里去了,想了一下,同样是一个缩进的代码块,为什么不能用if来解决呢!不就是个:

的问题。。。

TIL

总之学到了contextlib里的一些有用的函数和装饰器,也第一次发现with可以放个context。

虽然放多个context的动态构造还有待研究,with 后面的代码块也不能填一个元组或者列表。。惆怅。。

好啦!今天的分享到这里就结束了,希望大家持续关注马哥教育官网,每天都会有大量优质内容与大家分享!声明:文章转载于网络,版权归原作者所有,如有侵权,请及时联系删除!

python培训班骗局-马哥教育官网-专业Linux培训班,Python培训机构相关推荐

  1. python训练营免费领取-马哥教育官网-专业Linux培训班,Python培训机构

    [课程第一天] [课程第二天] [课程第三天] [课程第四天] [课程第五天] [课程第六天] [课程第七天] 三.学习的具体平台和方式 1.学习的平台 以录播视频和文字版本为主,QQ社群资深工程师答 ...

  2. 自动化专业学python有用吗-马哥教育官网-专业Linux培训班,Python培训机构

    今天小编要来说一下Python自动化的学习思路, 对于刚刚进入的测试行业的人来说,未来该怎么样朝着自动化方向发展,即使接触到了自动化测试,又该从何下手去学呢? 简单的说, 做测试做的好,会了接口,会了 ...

  3. python是什么-马哥教育官网-专业Linux培训班,Python培训机构

    今天小编要跟大家分享的文章是Python中的列表是什么?熟悉Python的小伙伴们都知道列表的定义比较简单,它由一系列按特定顺序排列的元素组成. 你可以创建包含字母表中所有字母.数字0~9或所有家庭成 ...

  4. 自学python 知乎-马哥教育官网-专业Linux培训班,Python培训机构

    一直在学习Python, 近来找到一本Python神书 500 line or less.有兄弟提到了git的源码,这儿不只是源码,而是这么一本书,现在还没出书,可是在网上有现已看到了 review版 ...

  5. 如何自学python知乎-马哥教育官网-专业Linux培训班,Python培训机构

    一直在学习Python, 近来找到一本Python神书 500 line or less.有兄弟提到了git的源码,这儿不只是源码,而是这么一本书,现在还没出书,可是在网上有现已看到了 review版 ...

  6. python好学嘛-马哥教育官网-专业Linux培训班,Python培训机构

    从2013年开始接触Python以来,我体验过阅读书籍,学习MOOC,查阅文档,谷歌搜索,逛编程社区.现在仍在学习Python中,走了很多的弯路.成功的道路各有不同,失败的地方却是种种.我想把我学习P ...

  7. python使用教程-马哥教育官网-专业Linux培训班,Python培训机构

    今天和大家分享一下零基础 1.安装Python 官方网址:www.Python.org,选择downloads,然后根据自己的操作系统选择相对应的栏目点击进去. 至于没有编程基础的直接学新版的3.0系 ...

  8. python类型转换-马哥教育官网-专业Linux培训班,Python培训机构

    今天马哥教育要跟大家分享的文章是类型转换是什么?我们要跟大家探讨的是Python课程中类型转换的相关内容,比如将小数转化为小数如何表达?整数转化为字符如何表达? Python的几种最基本的数据类型,我 ...

  9. 济南python工资一般多少钱-马哥教育官网-专业Linux培训班,Python培训机构

    主角:李学员岗位:K1实施工程师地区:济南 薪资:8.5K [注:马哥教育学员喜讯旨在通过一小部分学员自主的.真实的分享,将学习方法,学习经验,学习成果分享给正在或即将进入马哥教育学习课程的小伙伴们! ...

最新文章

  1. Virtual Machine Remote Control Client Plus
  2. Download failed : Oracle JDK 7 is NOT installed,解决oracle jdk7的问题
  3. javascript对象数组的二维比较和插入
  4. android解析JSON数组
  5. python mysql res_python操作mysql(三)查询
  6. seo关键词布局,网页头部优化(TDK),网站优化(古志强网络营销师)
  7. 交通流量预测数据集解读
  8. 互联网早报:腾讯内测游戏社交 App“NokNok”,对标 Discord
  9. android客户端功能,推荐一个功能齐全的【玩Android客户端】
  10. Tigo Energy通过Stark Renováveis安装案例向巴西安装商展示优化技术
  11. android圆角glide,Glide加载圆角图片的方法
  12. 【论文速读】自动解题+认知推理+常识发现
  13. 朋友找工作的奇葩规定
  14. 网络文件夹目前是以其他用户名和密码进行映射的
  15. 免费开源充电桩物联网云平台
  16. mklink和junction 详解
  17. python水浒传名字次数_梁山上,小李广的“小”是什么意思?“病关索”是生病的关索?...
  18. 【雷达系统导论】-雷达简介
  19. 国土资发〔2015〕16号 国土资源部关于进一步加强信息化工作统筹的若干意见
  20. 【小练习】使用selenium根据 歌单 多线程爬取网易云音乐的歌词

热门文章

  1. 剑指offer面试题33. 二叉搜索树的后序遍历序列(二叉树)(递归)
  2. 单例模式及多线程安全(C++版)
  3. 基于Qt的UDP协议实现及解析数据
  4. pyinstaller打包tensorflow+python程序成.exe各种坑(持续添加)
  5. php批量删除例子,php批量删除数据完整实例代码
  6. 移植最新版libmemcached到VC++的艰苦历程和经验总结(上)
  7. Android安装后没有完成和打开按钮
  8. gflags的使用实例(转载)
  9. struts中几种常用的Action
  10. Qt与VS2005/2008的完美配合(转)