zoukankan      html  css  js  c++  java
  • 上下文管理器__enter__和__exit__

    直接上代码:

     1 import os
     2 
     3 class Open(object):
     4     def __init__(self, file):
     5         self.file = file
     6 
     7     def __enter__(self):
     8         print('实例化的时候调用此代码块,若使用as则返回实例对象给as的对象')
     9         self.f = open(self.file)
    10         return self  # 返回实例是为了调用类方法
    11 
    12     def __exit__(self, exc_type, exc_val, exc_tb):  # 三个参数分别代表错误类型,错误值,错误追踪traceback
    13         print('Exit...')
    14         print(exc_tb)
    15         print(exc_type)
    16         print(exc_val)
    17         self.f.close()
    18 
    19     @property   # 装饰器,以属性的方式调用方法
    20     def say_name(self):
    21         return os.path.dirname(os.path.abspath(__file__))
    22 
    23 
    24 if __name__ == '__main__':
    25     with Open(r'bin/aa.py') as f:  # 通过with的方式实例化类,会触发类的__enter__方法,若__enter__有返回值,则把返回值赋值给as的对象
    26         print('======')
    27         print(f.say_name)
    28         print('------')  # 以上代码块执行完毕触发__exit__方法
    29         print(abcd)  # 此处不存在变量abcd,程序会抛出异常并且终止,但是因为有__exit__方法,错误信息会被吞掉,并直接执行__exit__方法
    30         print('.....')  # 上一行抛异常,此处不会执行
    31     print('lalala')  # 上一行抛异常,此处不会执行

    运行结果:

    C:UserslwjAppDataLocalProgramsPythonPython37python.exe D:/02Project/pacho/12day/st_上下文管理.py
    实例化的时候调用此代码块,若使用as则返回实例对象给as的对象
    ======
    D:2Projectpacho12day
    ------
    Exit...
    <traceback object at 0x0000000001FFDB48>
    <class 'NameError'>
    name 'abcd' is not defined
    Traceback (most recent call last):
      File "D:/02Project/pacho/12day/st_上下文管理.py", line 29, in <module>
        print(abcd)  # 此处不存在变量abcd,程序会抛出异常并且终止,但是__exit__方法返回为False(with中的代码块出现了异常),错误信息会被吐出,并直接执行__exit__方法
    NameError: name 'abcd' is not defined
    
    Process finished with exit code 1

    下面说下__exit__的返回值,举例:

     1 import os
     2 
     3 class Open(object):
     4     def __init__(self, file):
     5         self.file = file
     6 
     7     def __enter__(self):
     8         print('实例化的时候调用此代码块,若使用as则返回实例对象给as的对象')
     9         self.f = open(self.file)  # 此处是为了能够调用close() 方法
    10         return self  # 返回实例是为了调用类方法
    11 
    12     def __exit__(self, exc_type, exc_val, exc_tb):  # 三个参数分别代表错误类型,错误值,错误追踪traceback
    13         print('Exit...')
    14         print(exc_tb)
    15         print(exc_type)
    16         print(exc_val)
    17         self.f.close()
    18         return True  # 如果exit返回True则吞掉所有异常并结束with语句;如果exit返回False,则吐出异常
    19 
    20     @property   # 装饰器,以属性的方式调用方法
    21     def say_name(self):
    22         return os.path.dirname(os.path.abspath(__file__))
    23 
    24 
    25 if __name__ == '__main__':
    26     with Open(r'bin/aa.py') as f:  # 通过with的方式实例化类,会触发类的__enter__方法,若__enter__有返回值,则把返回值赋值给as的对象,即 f = 实例.__enter__()
    27         print('======')
    28         print(f.say_name)
    29         print('------')  # 以上代码块执行完毕触发__exit__方法
    30         print(abcd)  # 此处不存在变量abcd,程序会抛出异常并且终止,但是因为有__exit__方法,错误信息会被吞掉,并直接执行__exit__方法
    31         print('.....')  # 上一行抛异常,则直接执行exit方法,此行不会被执行,with语句结束
    32     print('lalala')  # 上一行抛异常,因为exit返回为True,此行会被执行

    执行的结果:

     1 C:UserslwjAppDataLocalProgramsPythonPython37python.exe D:/02Project/pacho/12day/st_上下文管理.py
     2 实例化的时候调用此代码块,若使用as则返回实例对象给as的对象
     3 ======
     4 D:2Projectpacho12day
     5 ------
     6 Exit...
     7 <traceback object at 0x000000000200DB08>
     8 <class 'NameError'>
     9 name 'abcd' is not defined
    10 lalala
    11 
    12 Process finished with exit code 0
  • 相关阅读:
    Http协议的断点续传下载器,使用观察者模式监视下载进度,使用xml保存下载进度。
    C++ 复制到粘贴板
    编译防火墙——C++的Pimpl惯用法解析
    字符串输出
    windows路径操作API函数
    Boost解析xml——xml写入
    智能指针shared_ptr
    Boost 解析xml——插入Item
    ListCtrl添加右键菜单(在对话框类中)
    抓包工具Charles的使用说明
  • 原文地址:https://www.cnblogs.com/wjlv/p/11594092.html
Copyright © 2011-2022 走看看