python中的with语句使用于对资源进行访问的场合,在程序处理过程中是否异常都会执行__enter__(self)方法,exit(‘清理’)方法操作,释放被访问的资源,比如有文件读写后自动关闭、线程中锁的自动获取和释放都可以使用。
用open打开一个文件进行读写时,都有可能产生IOError。而且文件每次使用完毕后必须关闭,因为文件对象会占用操作系统的资源,并且操作系统同一时间能打开的文件数量也是有限的,Python引入with语句来自动帮我们调用close()方法和预防异常。
#文件的写
with open('/Users/Bright/test.txt', 'w') as f:
f.write('Hello, world!')
#文件的读取
with open('/Users/Bright/test.txt', 'r') as f:
print(f.read())
Python ,with的使用在线程只能中使用,可以自动使用和释放锁。
import threading
import time
#全局变量多个线程可以读写,传递数据
mutex_num=0
mutex=threading.Lock() #创建一个锁
class Mythread(threading.Thread):
def run(self):
global mutex_num
with mutex: # with Lock的作用相当于自动获取和释放锁
for i in range(8800000): #锁定期间,其他线程不可以干活
mutex_num+=1
#上面3行的和下面3行的代码是等价的
# if mutex.acquire(1):#上锁成功往下运行,没有锁住就一直等待,1代表独占
# for i in range(8800000): #锁定期间,其他线程不可以执行任务
# mutex_num+=1
# mutex.release() #释放锁
print(mutex_num)
mythread=[]
for i in range(3):
t=Mythread()
t.start()
mythread.append(t)
for t in mythread:
t.join()
print("threading end.........")
基本思想是with所求值的对象必须有一个__enter__()方法,一个__exit__()方法。紧跟with后面的语句被求值后,
返回对象的__enter__()方法被调用,这个方法的返回值将被赋值给as后面的变量。当with后面的代码块全部被执行完之后,将调用前面返回对象的__exit__()方法。with真正强大之处是它可以处理异常。他的__exit__方法有三个参数val,type 和 trace,这些参数在异常处理中相当有用。
class Sample:
def __enter__(self):
# __enter__()方法首先被执行
print(self)
return self
def __exit__(self, type, value, trace):
#函数运行结束,最后__exit__()方法被调用
print "type:", type
print "value:", value
print "trace:", trace
def run(self):
num = 1/0
# num = 1
# num = 1时,<__main__.Sample instance at 0x024838C8>
# type: None
# value: None
# trace: None
return num
# __enter__()方法返回的值 ,赋值给变量’sample’
with Sample() as sample:
sample.run()
# <__main__.Sample instance at 0x025638C8>
# type: <type 'exceptions.ZeroDivisionError'>
# value: integer division or modulo by zero
# trace: <traceback object at 0x02563940>
# Traceback (most recent call last):
# File "E:/Data/IT/project/withtext.py", line 66, in <module>
# sample.run()
# File "E:/Data/IT/project/withtext.py", line 61, in run
# num = 1/0
# ZeroDivisionError: integer division or modulo by zero