zoukankan      html  css  js  c++  java
  • Python中with用法详解

    一 、with语句的原理

    • 上下文管理协议(Context Management Protocol):包含方法 __enter__()__exit__(),支持该协议的对象要实现这两个方法。
    • 上下文管理器(Context Manager):支持上下文管理协议的对象,这种对象实现了__enter__()__exit__()方法。上下文管理器定义执行with语句时要建立的运行时上下文,负责执行with语句块上下文中的进入与退出操作。通常使用with语句调用上下文管理器,也可以通过直接调用其方法来使用。

    说完上面两个概念,我们再从with语句的常用表达式入手,一段基本的with表达式,其结构是这样的:

    1 with EXPR as VAR:
    2 
    3     BLOCK

    其中EXPR可以是任意表达式;as VAR是可选的。其一般的执行过程是这样的:

    1. 执行EXPR,生成上下文管理器context_manager;
    2. 获取上下文管理器的__exit()__方法,并保存起来用于之后的调用;
    3. 调用上下文管理器的__enter__()方法;如果使用了as子句,则将__enter__()方法的返回值赋值给as子句中的VAR;
    4. 执行BLOCK中的表达式;
    5. 不管是否执行过程中是否发生了异常,执行上下文管理器的__exit__()方法,__exit__()方法负责执行“清理”工作,如释放资源等。如果执行过程中没有出现异常,或者语句体中执行了语句break/continue/return,则以None作为参数调用__exit__(None, None, None);如果执行过程中出现异常,则使用sys.exc_info得到的异常信息为参数调用__exit__(exc_type, exc_value, exc_traceback)
    6. 出现异常时,如果__exit__(type, value, traceback)返回False,则会重新抛出异常,让with之外的语句逻辑来处理异常,这也是通用做法;如果返回True,则忽略异常,不再对异常进行处理。

    二、自定义上下文管理器

      Pythonwith语句是提供一个有效的机制,让代码更简练,同时在异常产生时,清理工作更简单。

     1 # coding = utf-8
     2 # 2019/7/19  Luckyxxt:有趣的事,Python永远不会缺席!
     3 #!/usr/bin/env python
     4 
     5 class DBManager(object):
     6     def __init__(self):
     7         pass
     8 
     9     def __enter__(self):
    10         print('__enter__')
    11         return self
    12 
    13     def __exit__(self, exc_type, exc_val, exc_tb):
    14         print('__exit__')
    15         return True
    16 
    17 def getInstance():
    18         return DBManager()
    19 
    20 with getInstance() as dbManagerIns:
    21     print('with demo')

      with后面必须跟一个上下文管理器,如果使用了as,则是把上下文管理器的 __enter__() 方法的返回值赋值给 target,target 可以是单个变量,或者由“()”括起来的元组(不能是仅仅由“,”分隔的变量列表,必须加“()”)

    代码运行结果如下:

    1 '''
    2 __enter__
    3 with demo
    4 __exit__
    5 
    6 '''

    结果分析:当我们使用with的时候,__enter__方法被调用,并且将返回值赋值给as后面的变量,并且在退出with的时候自动执行__exit__方法

     1 class With_work(object):
     2     def __enter__(self):
     3         """进入with语句的时候被调用"""
     4         print('enter called')
     5         return "xxt"
     6 
     7     def __exit__(self, exc_type, exc_val, exc_tb):
     8         """离开with的时候被with调用"""
     9         print('exit called')
    10 
    11 
    12 with With_work() as f:
    13     print(f)
    14     print('hello with')
    1 '''
    2 enter called
    3 xxt
    4 hello with
    5 exit called
    6 
    7 '''

    三、总结

      自定义上下文管理器来对软件系统中的资源进行管理,比如数据库连接、共享资源的访问控制等。

           

  • 相关阅读:
    Azure PowerShell (2) 修改Azure订阅名称
    Windows Azure Platform Introduction (11) 了解Org ID、Windows Azure订阅、账户
    Azure PowerShell (3) 上传证书
    Azure PowerShell (1) PowerShell入门
    Windows Azure Service Bus (2) 队列(Queue)入门
    Windows Azure Service Bus (1) 基础
    Windows Azure Cloud Service (10) Role的生命周期
    Windows Azure Cloud Service (36) 在Azure Cloud Service配置SSL证书
    Android studio 使用心得(一)—android studio快速掌握快捷键
    android 签名、混淆打包
  • 原文地址:https://www.cnblogs.com/pythonbao/p/11211347.html
Copyright © 2011-2022 走看看