一、python上下文介绍:

  python中的上下文,指的就是代码所执行的环境状态,或者运行的场景

  python上下文管理器规定了某个对象的使用范围,当进入或者离开了使用范围,会有相应的操作,多用于资源的分配和释放上,即在开始时分配资源,结束时释放资源。

  如文件的读写,在读写前,需要先打开文件,在读写完成后,需要关闭文件。再如数据库的操作,在操作前,需要先连接数据库,结束后,需要释放连接等。

二、上下文管理器的使用: 

  下面看看资源的创建和释放场景(以数据库的操作为例):

  

class DataBase(object):

  def __init__(self):

    self.connect = False
  def connect(self):     self.connect = True
def close(self):
self.connect = False
def query(self):
if self.connect:
return "query data"
else:
raise ValueError("db not connected") def handle_query():
db = DataBase()
db.connect()
print("db query:", db.query())
db.close() if __name__=="__main__":
handle_query()

  上述代码很简单,针对数据类DataBase,我们提供了connect,close,query三个常规的db交互接口。

  普通的功能实现是没有问题的,但是我们都知道,在web交互中,数据库的操作是最频繁的,也就是说,我们每次在操作数据库的时候,都需要进行数据库类实例化,连接,关闭操作。显然这个和pythonic不符合的。

  然后为了上面的代码更加的优雅,我们想到了python中的一个黑魔法,装饰器

  我们可以将上述代码数据库的连接和关闭封装成一个闭包,然后通过装饰器对上面的代码进行改写:

class DataBase(object):
def __init__(self):
self.connect = False
def conn(self):
self.connect = True
def close(self):
self.connect = False
def query(self):
if self.connect:
return "query data"
else:
raise ValueError("db not connected") def dbconn(fun):
def wrapper(*args, **kwargs):
db = DataBase()
db.conn()
fun(db, *args, **kwargs)
db.close()
return wrapper @dbconn
def handle_query(db=None):
print("query:", db.query) if __name__=="__main__":
handle_query()

  我们封装了一个dbconn的装饰器,通过使用@dbconn装饰器,实现了数据库连接和释放的代码的复用,对比上面的代码,可以发现,使用装饰器相对优雅了很多

  但是每个装饰器都需要先定义一下db的资源句柄,看起来还是没有那么优雅。下面我们通过上下文管理器的方式实现数据库操作:

class DataBase(object):
def __init__(self):
self.connect = False
def conn(self):
self.connect = True
def close(self):
self.connect = False
def query(self):
return "query data"
def __enter__(self):
self.conn()
return self
def __exit__(self, exc_type, exc_value, exc_db):
self.close() def handle_query():
with DataBase() as db:
print("query:", db.query) if __name__=="__main__":
handle_query()

  对比上面的上下文管理器实现数据库操作的代码,可以发现,在定义数据库类DataBase的时候,虽然多写了几行代码,但是我们的代码可读性变得更好了。

三、上下文管理协议

  实现了上下文协议的对象叫上下文管理器

  那么什么是上下文协议呢?即实现了__enter__() 和__exit__()方法,也就是实现了上下文管理协议

  上下文表达式必须要返回一个上下文管理器对象

  代码结构如下:

class Context:
def __init__(self, filename, fileMode="w"):
self.obj = open(filename, fileMode)
def __enter__(self):
return self.obj
def __exit__(self, exc_type, exc_value, exc_db):
self.obj.close() with Context("C:\Users\admin\Desktop\1.txt") as f:
f.write("something")

  如上图,Context类实现了__enter__和__exit__两个上下文管理器协议,当Context被调用或实例化的时候,创建了上下文管理器

  配合with语句使用的时候,上下文管理器会自动调用__enter__方法,然后进入运行时上下文环境,并将__enter__函数返回值赋值给as从句变量 f

  当f.write("something")执行完毕退出with语句块或者是出现异常导致程序退出时,会执行__exit__方法,并把异常信息传递给后面的参数exc_type, exc_value, exc_db

  如果__exit__方法返回True,则with语句块不会显示的抛出异常,程序终止

  如果__exit__方法返回None或者False,异常会被主动抛出,程序终止。

四、上下文管理器工具

  python为了使代码更加的优雅,还提供了一个模块contextlib 来实现更函数式的上下文管理器

from contextlib import contextmanager

@contextmanager
def context(filename, fileMode="w"):
f = open(filename, fileMode)
try:
yield f
except Exception as e:
print(e)
finally:
f.close() with context("C:\\Users\\admin\\Desktop\\1.txt") as f:
f.write("write something1")

  上图通过contextmanager装饰器定义了一个上下文管理器函数context,通过with context("C:\\Users\\admin\\Desktop\\1.txt") 返回上下文管理器对象

  然后调用函数隐式的__enter__函数,并将结果通过yield返回

  然后通过返回的文件对象,执行文件的写入操作

  写入操作结束,退出上下文环境,执行了f.close()

五、with语句执行过程总结:

  1)执行上下文表达式 Context("C:\Users\admin\Desktop\1.txt"),获得上下文管理器

  2)加载上下文管理器的__enter__ 和 __exit__,以备后续调用

  3)调用__enter__(),方法,并返回文件对象 f 赋值给as从句变量

  4)执行with语句块的子语句块f.write("something")

  5)调用上下文管理器的__exit__(),如果是由于异常导致程序退出的,将type, value 和traceback作为参数传递给exit(),否则传三个None

     如果__exit__()返回值等于False,则异常会被显示的抛出,程序终止,否则,异常会被无视,继续执行。

  上下文管理器主要用于多线程/进程的变成中,因为涉及到上下文的切换

  

  

python上下文管理的更多相关文章

  1. python 上下文管理器

    作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 上下文管理器(context manager)是Python2.5开始支持的一种语 ...

  2. Python 上下文管理器和else块

    最终,上下文管理器可能几乎与子程序(subroutine)本身一样重要.目前,我们只了解了上下文管理器的皮毛--Basic 语言有with 语句,而且很多语言都有.但是,在各种语言中 with 语句的 ...

  3. Python上下文管理器

    在Python中让自己创建的函数.类.对象支持with语句,就实现了上线文管理协议.我们经常使用with open(file, "a+") as f:这样的语句,无需手动调用f.c ...

  4. python上下文管理器ContextLib及with语句

    http://blog.csdn.net/pipisorry/article/details/50444736 with语句 with语句是从 Python 2.5 开始引入的一种与异常处理相关的功能 ...

  5. Python上下文管理器 with

    对于系统资源的操作,如:文件操作.数据库操作等,我们往往打开文件.连接数据库后忘了将其close掉,这时就可能会引发异常,因此我们常用的做法是: # coding:utf-8 f = open(&qu ...

  6. Python上下文管理协议:__enter__和__exit__

    上下文管理器(context manager)是Python2.5开始支持的一种语法,用于规定某个对象的使用范围.一旦进入或者离开该使用范围,会有特殊操作被调用 (比如为对象分配或者释放内存).它的语 ...

  7. Python上下文管理器(Context managers)

    上下文管理器(Context managers) 上下文管理器允许你在有需要的时候,精确地分配和释放资源. 使用上下文管理器最广泛的案例就是with语句了.想象下你有两个需要结对执行的相关操作,然后还 ...

  8. python上下文管理器细读

    test 1 上下文管理器,将生成器转化为上下文管理器 import contextlib @contextlib.contextmanager def a(): print(1) yield pri ...

  9. 吃透Python上下文管理器

    什么是上下文管理器? 我们常见的with open操作文件,就是一个上下文管理器.如: with open(file, 'rb') as f: text = f.read() 那上下文管理器具体的定义 ...

随机推荐

  1. 5个常常被大家忽略的Python小技巧

    下面我挑选出的这几个技巧常常会被人们忽略,但它们在日常编程中能真正的给我们带来不少帮助. 1. 字典推导(Dictionary comprehensions)和集合推导(Set comprehensi ...

  2. 宝塔面板设置腾迅COS自动备份网站

    之前写了如何配置腾迅云COS并挂载到服务器中,今天看到宝塔面板中有腾迅云COS的插件,不过研究了下,只是将COS绑定在宝塔面板中,不能自动备份,需要用到宝塔的计划任务功能 1.下载腾迅云COS插件 2 ...

  3. F#正则表达式

    此词法分析器允许您使用F#计算表达式以非常声明的方式定义基于正则表达式的规则. F# 打开 Lexer 让 定义= lexerDefinitions { 做!addNextlineDefinition ...

  4. Android开发:Android Studio开发环境配置

    一.android studio下载: 1.Windows版: 下载地址:https://pan.baidu.com/s/1-sg4dN_2B5nn2YJf-C7XLQ 提取码:yedc 2.Mac版 ...

  5. [JLOI2016] 成绩比较

    推石子 首先设\(d[i]=\sum_{t=1}^{U[i]}t^{n-R[i]}(U[i]-t)^{R[i]-1}\),即第\(i\)门课程分数的合法分布方案数: 然后设\(f[i,j]\)表示前\ ...

  6. Python爬虫入门教程 47-100 mitmproxy安装与安卓模拟器的配合使用-手机APP爬虫部分

    1. 准备下载软件 介绍一款爬虫辅助工具mitmproxy ,mitmproxy 就是用于MITM的proxy,MITM中间人攻击.说白了就是服务器和客户机中间通讯多增加了一层.跟Fiddler和Ch ...

  7. Asp.Net Core微服务初体验

    ASP.Net Core的基本配置 .在VS中调试的时候有很多修改Web应用运行端口的方法.但是在开发.调试微服务应用的时候可能需要同时在不同端口上开启多个服务器的实例,因此下面主要看看如何通过命令行 ...

  8. 版本控制工具——Git常用操作(下)

    本文由云+社区发表 作者:工程师小熊 摘要:上一集我们一起入门学习了git的基本概念和git常用的操作,包括提交和同步代码.使用分支.出现代码冲突的解决办法.紧急保存现场和恢复现场的操作.学会以后已经 ...

  9. SpringBoot从零到上线

    SpringBoot精要 SpringBoot的四个核心 1.自动配置:针对很多Spring应用程序常见的应用功能,SpringBoot能自动提供相关配置. 在任何Spring应用程序的源代码中,都可 ...

  10. 享元模式 FlyWeight 结构型 设计模式(十五)

    享元模式(FlyWeight)  “享”取“共享”之意,“元”取“单元”之意. 意图 运用共享技术,有效的支持大量细粒度的对象. 意图解析 面向对象的程序设计中,一切皆是对象,这也就意味着系统的运行将 ...