您的位置: 网站首页> python进阶> 当前文章

什么是上下文管理器,基于类自定义上下文管理器

老董-我爱我家房产SEO2021-11-18158围观,118赞

  在文件操作时经常用with as 语句,同时接触了上下文管理器的概念。其实上下文是context直译的说法,在程序中用来表示某段代码所处的前后环境,比如在文件中写入数据,写入之前要打开文件,写入之后要关闭文件。

  在python中,一个类只要实现了__enter__()和__exit__()这2个方法就代表实现了上下文管理协议。

  在python中,同时包含__enter__()和__exit__()方法的对象就是上下文管理器。

  实际使用上下文管理器离不开with语法,with语法格式如下:

  
with context_expression as var:
  # 一段代码块

  上述代码中context_expression代表上下文管理器,as var可以省略,但是往往会用到这个变量所以不省略。

  __enter__:进入with语法块之前调用,返回值会赋值给as后面的变量

  __exit__:退出with语法块后自动调用的方法,可以拿到with语句块内的异常详细信息

  我们自己写一个类来验证下

class TestWith:

    def __enter__(self):
        print('__enter__')
        return '...python66...'

    def __exit__(self, exc_type, exc_value, exc_tb):
        print('---- exc_type: %s' % exc_type)
        print('==== exc_value: %s' % exc_value)
        print('**** exc_tb: %s' % exc_tb)
        print('...end...')

with TestWith() as var:
  print(f'value:{var}')
__enter__
value:...python66...
---- exc_type: None
==== exc_value: None
**** exc_tb: None
...end...

  当with中执行的代码发生异常时,异常信息会被发送到 __exit__()方法的三个参数中:

  1)exc_type : 异常类型

  2)exc_val : 异常值

  3)exc_tb : 异常堆栈信息追踪

  我们在with语句块中写点能抛出异常的代码测试下

class TestWith:

    def __enter__(self):
        print('__enter__')
        return '...python66...'

    def __exit__(self, exc_type, exc_value, exc_tb):
        print('---- exc_type: %s' % exc_type)
        print('==== exc_value: %s' % exc_value)
        print('**** exc_tb: %s' % exc_tb)
        print('...end...')

with TestWith() as var:
  print(f'value:{var}')
  print(haha)
__enter__Traceback (most recent call last):

value:...python66...
---- exc_type: <class 'NameError'>
==== exc_value: name 'haha' is not defined
**** exc_tb: <traceback object at 0x0000000017C65F08>
...end...
  File "C:UsersAdministratorDesktop	est.py", line 73, in <module>
    print(haha)
NameError: name 'haha' is not defined

  如果__exit__()返回的是True,那么这个异常就被忽略。如果__exit__()返回的是True以外的任何东西,那么这个异常才被with语句抛出。

class TestWith:

    def __enter__(self):
        print('__enter__')
        return '...python66...'

    def __exit__(self, exc_type, exc_value, exc_tb):
        print('---- exc_type: %s' % exc_type)
        print('==== exc_value: %s' % exc_value)
        print('**** exc_tb: %s' % exc_tb)
        print('...end...')
        return True

with TestWith() as var:
  print(f'value:{var}')
  print(haha)
__enter__
value:...python66...
---- exc_type: 
==== exc_value: name 'haha' is not defined
**** exc_tb: <traceback object at 0x0000000017C79E88>
...end...

很赞哦!

python编程网提示:转载请注明来源www.python66.com。
有宝贵意见可添加站长微信(底部),获取技术资料请到公众号(底部)。同行交流请加群 python学习会

文章评论

    什么是上下文管理器,基于类自定义上下文管理器文章写得不错,值得赞赏

站点信息

  • 网站程序:Laravel
  • 客服微信:a772483200