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

__exit____enter__函数with语句的组合应用

 

by:授客 QQ1033553122

简介

设计对象类时,我们可以为对象类新增两个方法,一个是__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。另外,如果该函数返回True1类值的Boolean真值,那么将忽略“代码块”中的异常,停止执行“代码块”中剩余语句,但是会继续执行“代码块”后面的语句;如果函数返回类似0False类的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-----------')
 
运行结果
Python <wbr>__exit__,__enter__函数with语句的组合应用
如上,代码块运行前调用了__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-----------')
 
运行结果
Python <wbr>__exit__,__enter__函数with语句的组合应用
对比实验:
在上述的基础上继续修改代码
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-----------')
 
运行结果:
Python <wbr>__exit__,__enter__函数with语句的组合应用
注意:
1、抛异常后,代码块中剩余的语句没有再继续运行
2、如果在上述的基础上,把代码中的 12/0剪切后放到password(self),抛出异常的异常信息是不会传递给__exit__函数的
@property
def password(self):
12/0
return self._password
 
运行结果如下,
Python <wbr>__exit__,__enter__函数with语句的组合应用

 

 

 

原文地址:https://www.cnblogs.com/shouke/p/10157613.html