Python with语句上下文管理器两种实现方法分析

本文实例讲述了Python with语句上下文管理器。分享给大家供大家参考,具体如下:

在编程中会经常碰到这种情况:有一个特殊的语句块,在执行这个语句块之前需要先执行一些准备动作;当语句块执行完成后,需要继续执行一些收尾动作。例如,文件读写后需要关闭,数据库读写完毕需要关闭连接,资源的加锁和解锁等情况。

对于这种情况python提供了上下文管理器(Context Manager)的概念,可以通过上下文管理器来定义/控制代码块执行前的准备动作,以及执行后的收尾动作。

一、为何使用上下文管理器

1、不使用上下文管理器的情况

通过try...finally语句执行异常处理和关闭句柄的动作。

logger = open("log.txt", "w")
try:
  logger.write('Hello ')
  logger.write('World')
finally:
  logger.close()
print logger.closed

2、使用上下文管理器

默认文件Python的内置file类型是支持上下文管理协议的。
使用上下文管理器with使得依据精简了很多。

with open("log.txt", "w") as logger:
  logger.write('Hello ')
  logger.write('World')
print logger.closed

二、实现上下文管理器实现上下文管理器有两种方式实现。方法一:类实现__enter__和__exit__方法。方法二:contextlib模块装饰器和生成器实现。

下面我们通过两种方法分别实现一个自定义的上下文管理器。

1、方法一:通过类实现__enter__和__exit__方法

class File(object):
 def __init__(self, file_name, method):
  self.file_obj = open(file_name, method)
 def __enter__(self):
  return self.file_obj
 def __exit__(self, type, value, traceback):
  self.file_obj.close()
with File('demo.txt', 'w') as opened_file:
 opened_file.write('Hola!')

实现__enter__和__exit__方法后,就能通过with语句进行上下文管理。

a、底层都发生了什么?

1、with语句先暂存了File类的__exit__方法,然后它调用File类的__enter__方法。
2、__enter__方法打开文件并返回给with语句,打开的文件句柄被传递给opened_file参数。
3、with语句调用之前暂存的__exit__方法,__exit__方法关闭了文件。

b、异常处理

关于异常处理,with语句会采取哪些步骤。

1. 它把异常的type,value和traceback传递给__exit__方法
2. 它让__exit__方法来处理异常
3. 如果__exit__返回的是True,那么这个异常就被忽略。
4. 如果__exit__返回的是True以外的任何东西,那么这个异常将被with语句抛出。

异常抛出

#异常抛出,_exit__返回的是True以外的任何东西,那么这个异常将被with语句抛出
class File(object):
 def __init__(self, file_name, method):
  self.file_obj = open(file_name, method)
 def __enter__(self):
  return self.file_obj
 def __exit__(self, type, value, traceback):
  self.file_obj.close()
  print "type:",type
  print "value:",value
  print "traceback:",traceback
with File('demo.txt', 'w') as opened_file:
 opened_file.undefined_function('Hola!')
#output================================================
# type: <type 'exceptions.AttributeError'>
# value: 'file' object has no attribute 'undefined_function'
# traceback: <traceback object at 0x000000000262D9C8>
#  opened_file.undefined_function('Hola!')
# AttributeError: 'file' object has no attribute 'undefined_function'

异常忽略:

#异常忽略,__exit__返回的是True,那么这个异常就被忽略。
class File(object):
 def __init__(self, file_name, method):
  self.file_obj = open(file_name, method)
 def __enter__(self):
  return self.file_obj
 def __exit__(self, exception_type, exception_value, traceback):
  print("Exception has been handled")
  self.file_obj.close()
  return True
with File('demo.txt', 'w') as opened_file:
 opened_file.undefined_function('Hola!')
# output==================================
# Exception has been handled

2、方法二:contextlib模块装饰器和生成器实现

这种方式实现更优雅,我个人更喜欢这种方式。

yield之前的代码由__enter__方法执行,yield之后的代码由__exit__方法执行。本质上还是__enter____exit__方法。

# coding:utf-8
import contextlib
@contextlib.contextmanager
def myopen(filename, mode):
 f = open(filename, mode)
 try:
  yield f.readlines()
 except Exception as e:
  print e
 finally:
  f.close()
if __name__ == '__main__':
 with myopen(r'c:\ip2.txt', 'r') as f:
  for line in f:
   print line

3、with语句上多个下文关联

直接通过一个with语句打开多个上下文,即可同时使用多个上下文变量,而不必需嵌套使用with语句。

class File(object):
 def __init__(self, file_name, method):
  self.file_obj = open(file_name, method)
 def __enter__(self):
  return self.file_obj
 def __exit__(self, exception_type, exception_value, traceback):
  self.file_obj.close()
  return True
with File('demo.txt', 'w') as f1,File('demo.txt','w') as f2:
 print f1,f2
# Output============================# <open file 'demo.txt', mode 'w' at 0x000000000263D150> <open file 'demo.txt', mode 'w' at 0x000000000263D1E0>

更多关于Python相关内容可查看本站专题:《Python数据结构与算法教程》、《Python Socket编程技巧总结》、《Python函数使用技巧总结》、《Python字符串操作技巧汇总》及《Python入门与进阶经典教程》

希望本文所述对大家Python程序设计有所帮助。

您可能感兴趣的文章:

  • Python中的with语句与上下文管理器学习总结
  • Python深入学习之上下文管理器
  • 深入解析Python中的上下文管理器
  • 正确理解python中的关键字“with”与上下文管理器
  • 深入学习Python中的上下文管理器与else块
  • Python标准模块--ContextManager上下文管理器的具体用法
  • Python上下文管理器和with块详解
  • python 上下文管理器使用方法小结
  • 详解Python中with语句的用法
  • 理解Python中的With语句
(0)

相关推荐

  • Python上下文管理器和with块详解

    上下文管理器和with块,具体内容如下 上下文管理器对象存在的目的是管理 with 语句,就像迭代器的存在是为了管理 for 语句一样. with 语句的目的是简化 try/finally 模式.这种模式用于保证一段代码运行完毕后执行某项操作,即便那段代码由于异常. return 语句或 sys.exit() 调用而中止,也会执行指定的操作. finally 子句中的代码通常用于释放重要的资源,或者还原临时变更的状态. ==上下文管理器协议包含enter和exit两个方法==. with 语句开

  • Python中的with语句与上下文管理器学习总结

    0.关于上下文管理器 上下文管理器是可以在with语句中使用,拥有__enter__和__exit__方法的对象. with manager as var: do_something(var) 相当于以下情况的简化: var = manager.__enter__() try: do_something(var) finally: manager.__exit__() 换言之,PEP 343中定义的上下文管理器协议允许将无聊的try...except...finally结构抽象到一个单独的类中,

  • 深入解析Python中的上下文管理器

    1. 上下文管理器是什么? 举个例子,你在写Python代码的时候经常将一系列操作放在一个语句块中: (1)当某条件为真 – 执行这个语句块 (2)当某条件为真 – 循环执行这个语句块 有时候我们需要在当程序在语句块中运行时保持某种状态,并且在离开语句块后结束这种状态. 所以,事实上上下文管理器的任务是 – 代码块执行前准备,代码块执行后收拾. 上下文管理器是在Python2.5加入的功能,它能够让你的代码可读性更强并且错误更少.接下来,让我们来看看该如何使用. 2. 如何使用上下文管理器? 看

  • python 上下文管理器使用方法小结

    上下文管理器最常用的是确保正确关闭文件, with open('/path/to/file', 'r') as f: f.read() with 语句的基本语法, with expression [as variable]: with-block expression是一个上下文管理器,其实现了enter和exit两个函数.当我们调用一个with语句时, 依次执行一下步骤, 1.首先生成一个上下文管理器expression, 比如open('xx.txt'). 2.执行expression.en

  • 正确理解python中的关键字“with”与上下文管理器

    前言 如果你有阅读源码的习惯,可能会看到一些优秀的代码经常出现带有 "with" 关键字的语句,它通常用在什么场景呢?今天就来说说 with 和 上下文管理器. 对于系统资源如文件.数据库连接.socket 而言,应用程序打开这些资源并执行完业务逻辑之后,必须做的一件事就是要关闭(断开)该资源. 比如 Python 程序打开一个文件,往文件中写内容,写完之后,就要关闭该文件,否则会出现什么情况呢?极端情况下会出现 "Too many open files" 的错误,

  • 详解Python中with语句的用法

    引言 with 语句是从 Python 2.5 开始引入的一种与异常处理相关的功能(2.5 版本中要通过 from __future__ import with_statement 导入后才可以使用),从 2.6 版本开始缺省可用(参考 What's new in Python 2.6? 中 with 语句相关部分介绍).with 语句适用于对资源进行访问的场合,确保不管使用过程中是否发生异常都会执行必要的"清理"操作,释放资源,比如文件使用后自动关闭.线程中锁的自动获取和释放等. 术

  • Python标准模块--ContextManager上下文管理器的具体用法

    写代码时,我们希望把一些操作放到一个代码块中,这样在代码块中执行时就可以保持在某种运行状态,而当离开该代码块时就执行另一个操作,结束当前状态:所以,简单来说,上下文管理器的目的就是规定对象的使用范围,如果超出范围就采取"处理". 这一功能是在Python2.5之后引进的,它的优势在于可以使得你的代码更具可读性,且不容易出错. 1 模块简介 在数年前,Python 2.5 加入了一个非常特殊的关键字,就是with.with语句允许开发者创建上下文管理器.什么是上下文管理器?上下文管理器就

  • 深入学习Python中的上下文管理器与else块

    前言 本文主要个大家介绍了关于Python上下文管理器与else块的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧. 在开始之前,我们先来看看下面这段话: 最终,上下文管理器可能几乎与子程序(subroutine)本身一样重要.目前,我们只了解了上下文管理器的皮毛--Basic 语言有with 语句,而且很多语言都有.但是,在各种语言中 with 语句的作用不同,而且做的都是简单的事,虽然可以避免不断使用点号查找属性,但是不会做事前准备和事后清理.不要觉得名字一样,就意

  • Python深入学习之上下文管理器

    上下文管理器(context manager)是Python2.5开始支持的一种语法,用于规定某个对象的使用范围.一旦进入或者离开该使用范围,会有特殊操作被调用 (比如为对象分配或者释放内存).它的语法形式是with...as... 关闭文件 我们会进行这样的操作:打开文件,读写,关闭文件.程序员经常会忘记关闭文件.上下文管理器可以在不需要文件的时候,自动关闭文件. 下面我们看一下两段程序: 复制代码 代码如下: # without context manager f = open("new.t

  • Python with语句上下文管理器两种实现方法分析

    本文实例讲述了Python with语句上下文管理器.分享给大家供大家参考,具体如下: 在编程中会经常碰到这种情况:有一个特殊的语句块,在执行这个语句块之前需要先执行一些准备动作:当语句块执行完成后,需要继续执行一些收尾动作.例如,文件读写后需要关闭,数据库读写完毕需要关闭连接,资源的加锁和解锁等情况. 对于这种情况python提供了上下文管理器(Context Manager)的概念,可以通过上下文管理器来定义/控制代码块执行前的准备动作,以及执行后的收尾动作. 一.为何使用上下文管理器 1.

  • Python中的上下文管理器和with语句的使用

    Python2.5之后引入了上下文管理器(context manager),算是Python的黑魔法之一,它用于规定某个对象的使用范围.本文是针对于该功能的思考总结. 为什么需要上下文管理器? 首先,需要思索下为什么需要引入上下文管理器. 在正常情况下,管理各种系统资源(如文件).数据库连接时,通常是先打开这些资源,执行完相应的业务逻辑,最后关闭资源. 举两个例子: 1.使用Python打开一个文件写入内容,之后需要关闭这个文件.如果不正常关闭的话可能会在文件操作时出现异常,因为系统允许你打开的

  • Python中的上下文管理器相关知识详解

    前言 with 这个关键字,对于每一学习Python的人,都不会陌生. 操作文本对象的时候,几乎所有的人都会让我们要用 with open ,这就是一个上下文管理的例子.你一定已经相当熟悉了,我就不再废话了. with open('test.txt') as f: print f.readlines() 什么是上下文管理器? 基本语法 with EXPR as VAR: BLOCK 先理清几个概念 1. 上下文表达式:with open('test.txt') as f: 2. 上下文管理器:o

  • Android开发中画廊视图Gallery的两种使用方法分析

    本文实例讲述了Android开发中画廊视图Gallery的两种使用方法.分享给大家供大家参考,具体如下: 第一种方法: 第一步:设计xml布局文件 代码如下:main.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_w

  • 详解python 破解网站反爬虫的两种简单方法

    最近在学爬虫时发现许多网站都有自己的反爬虫机制,这让我们没法直接对想要的数据进行爬取,于是了解这种反爬虫机制就会帮助我们找到解决方法. 常见的反爬虫机制有判别身份和IP限制两种,下面我们将一一来进行介绍. (一) 判别身份 首先我们看一个例子,看看到底什么时反爬虫. 我们还是以 豆瓣电影榜top250(https://movie.douban.com/top250) 为例.` import requests # 豆瓣电影榜top250的网址 url = 'https://movie.douban

  • python 上下文管理器及自定义原理解析

    这篇文章主要介绍了python 上下文管理器原理解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 Python 提供了 with 语法用于简化资源操作的后续清除操作,是 try/finally 的替代方法,实现原理建立在上下文管理器之上. Python 提供了一个 contextmanager 装饰器,更进一步简化上下管理器的实现方式. 上下文管理器是Python2.5之后才出现的概念.上下文管理器规定了某个对象的使用范围,当进入或者离开了使

  • Python实现上下文管理器的方法

    问题 你想自己去实现一个新的上下文管理器,以便使用with语句. 解决方案 实现一个新的上下文管理器的最简单的方法就是使用 contexlib 模块中的 @contextmanager 装饰器. 下面是一个实现了代码块计时功能的上下文管理器例子: import time from contextlib import contextmanager @contextmanager def timethis(label): start = time.time() try: yield finally:

随机推荐

其他