前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Python __exit__,__enter__函数with语句的组合应用

Python __exit__,__enter__函数with语句的组合应用

作者头像
授客
发布2019-09-11 15:30:05
7030
发布2019-09-11 15:30:05
举报
文章被收录于专栏:授客的专栏授客的专栏

简介

设计对象类时,我们可以为对象类新增两个方法,一个是__enter(self)__,一个是__exit__(self, exc_type, exc_val, exc_tb)。

__enter(self)__

负责返回一个值,该返回值将赋值给as子句后面的var_name,通常返回对象自己,即“self”。函数优先于with后面的“代码块”(statements1,statements2,……)被执行。

__exit__(self, exc_type, exc_val, exc_tb)

执行完with后面的代码块后自动调用该函数。with语句后面的“代码块”中有异常(不包括因调用某函数,由被调用函数内部抛出的异常) ,会把异常类型,异常值,异常跟踪信息分别赋值给函数参数exc_type, exc_val, exc_tb,没有异常的情况下,exc_type, exc_val, exc_tb值都为None。另外,如果该函数返回True、1类值的Boolean真值,那么将忽略“代码块”中的异常,停止执行“代码块”中剩余语句,但是会继续执行“代码块”后面的语句;如果函数返回类似0,False类的Boolean假值、或者没返回值,将抛出“代码块”中的异常,那么在没有捕获异常的情况下,中断“代码块”及“代码块”之后语句的执行

with xxx as var_name:

# 代码块开始

statements1

statements2

……

# 代码块结束

# 代码快后面的语句

statements after code block

代码演示1

#!/usr/bin/env python

# -*- coding:utf-8 -*-

__author__ = 'laiyu'

class User(object):

def __init__(self, username, password):

self._username = username

self._password = password

@property

def username(self):

return self._username

@username.setter

def username(self, username):

self._username = username

@property

def password(self):

return self._password

@password.setter

def password(self, password):

self._password = password

def __enter__(self):

print('auto do something before statements body of with executed')

return self

def __exit__(self, exc_type, exc_val, exc_tb):

print('auto do something after statements body of with executed')

if __name__ == '__main__':

boy = User('shouke', 'shouke2014')

print(boy.password)

with User('shouke', '2014') as user:

print(user.password)

print('---------end-----------')

运行结果

如上,代码块运行前调用了__enter__函数,代码块运行完,自动调用了__exit__函数

代码演示2

更改上述部分代码如下,继续运行

def __exit__(self, exc_type, exc_val, exc_tb):

print('auto do something after statements body of with executed')

print('exc_type:', exc_type)

print('exc_val:', exc_val)

print('exc_tb:', exc_tb)

return False

if __name__ == '__main__':

boy = User('shouke', 'shouke2014')

print(boy.password)

with User('shouke', '2014') as user:

print(user.password)

12/0

print('after execption')

print('---------end-----------')

运行结果

对比实验:

在上述的基础上继续修改代码

def __exit__(self, exc_type, exc_val, exc_tb):

print('auto do something after statements body of with executed')

print('exc_type:', exc_type)

print('exc_val:', exc_val)

print('exc_tb:', exc_tb)

return True

if __name__ == '__main__':

boy = User('shouke', 'shouke2014')

print(boy.password)

with User('shouke', '2014') as user:

print(user.password)

12/0

print('after execption')

print('---------end-----------')

运行结果:

注意:

1、抛异常后,代码块中剩余的语句没有再继续运行

2、如果在上述的基础上,把代码中的 12/0剪切后放到password(self)中,抛出异常的异常信息是不会传递给__exit__函数的

@property

def password(self):

12/0

return self._password

运行结果如下,

代码语言:javascript
复制
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2017-03-09 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 简介
  • 代码演示1
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档