背景知识:
1 打印sys.exc_info()
如果没有异常返回
import sys
1/1
print(sys.exc_info())
------------------------
(None, None, None)
有异常返回
import sys
try:
a=1/0
except:
error=sys.exc_info()
print(error)
print(error[0])
print(error[1])
print(error[2])
------------------------------
(<class 'ZeroDivisionError'>, ZeroDivisionError('division by zero',), <traceback object at 0x0000000
00232B088>)
<class 'ZeroDivisionError'>
division by zero
<traceback object at 0x000000000232B088>
2 with后面的对象必须要有__enter__(),__exit__()方法否则会报错: AttributeError
>>> def P():
... pass
...
>>> a=P()
>>> dir(a)
['__bool__', '__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__
getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__ne__'
, '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__s
ubclasshook__']
>>> with a as foo:
... print("error")
...
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: __enter__
好切入正题。
使用with处理的对象必须有__enter__(),__exit__()这两个方法(with后面的对象、with后面所返回的对象)。__enter__()方法在with语句包裹起来的代码块执行之前进入,__exit__()方法在语句执行完退出后运行。
紧跟with后面的语句被求值后,返回对象的__enter__()方法被调用,这个方法的返回值将被赋值给as后面的变量。
with语句适用于对资源访问的场合,不管执行过程中有没有异常,都会执行必要的清理工作,释放资源。比如文件使用后的自动关闭,线程中锁的自动获取和释放。
class Sample:
def __enter__(self):
print ("In __enter__()")
return "Foo"
def __exit__(self, type, value, trace):
print ("In __exit__()")
def get_sample():
return Sample()
with get_sample() as sample:
print ("sample:", sample)
在with后面的代码块抛出任何异常时,则使用 sys.exc_info的异常信息为参数调用 __exit__(exc_type, exc_value, exc_traceback)将type,value和trace传给__exit__()方法,开发库时,清理资源,关闭文件等等操作,都可以放在__exit__方法当中。
class Sample:
def __enter__(self):
return self
def __exit__(self, type, value, trace):
print ("type:", type)
print ("value:", value)
print ("trace:", trace)
def do_something(self):
a= 1/0
return a + 1
with Sample() as sample:
sample.do_something()
-----------------------------------------
type: <class 'ZeroDivisionError'>
value: division by zero
trace: <traceback object at 0x000000000234C508>
Traceback (most recent call last):
File "C:UsersAdministratorDesktopc.py", line 15, in <module>
sample.do_something()
File "C:UsersAdministratorDesktopc.py", line 11, in do_something
bar = 1/0
ZeroDivisionError: division by zero