python 上下文管理器


# 上下文管理器的用法


# 1.资源清理************************************************************************

# 数据库连接
import pymysql
class DBConnection(object):

def __init__(self,user=None,password=None,dbname=None,host='localhost'):
self.user = user
self.password = password
self.host = host
self.dbname = dbname

def __enter__(self):
self.connection = pymysql.connect(self.host,self.user,self.password,self.dbname )
return self.connection.cursor()

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

self.connection.close()


with DBConnection(user='root',password='root',dbname='test2') as db: #as 后边的变量接受__enter__返回的对象
db.execute('select 1+1')
a = db.fetchall()
print(a)


# 2.避免重复(传播异常)************************************************************************

class BubbleException(object):

def __enter__(self):
return self

def __exit__(self, exc_type, exc_val, exc_tb):
if exc_val:
print('bubbling up eception :%s' %exc_val)
return False

# with BubbleException():
# a = 5+5


# with BubbleException():
# a = 5/0


# 2.避免重复(终止异常)************************************************************************

class SupressException(object):

def __enter__(self):
return self

def __exit__(self, exc_type, exc_val, exc_tb):
if exc_val:
print('supressing up eception :%s' %exc_val)
return True #尽量不要这么做

# 上述行为与以下示例是相似的
try:
['do something']
except:
pass

# with SupressException():
# a = 5+5
# print(a)
#
# with SupressException():
# a = 5/0
# print(a)

# 2.避免重复(处理特定异常的类)************************************************************************

class HandleValueError(object):

def __enter__(self):
return self

def __exit__(self, exc_type, exc_val, exc_tb):
if issubclass(exc_type,ValueError):
return True

return False

#特定的异常阻止抛出
with HandleValueError():
raise ValueError('wrong value')

#剩余的异常继续抛出
# with HandleValueError():
# raise TypeError('type error')

# 2.避免重复(不包括的子类,只捕获一个给定的异常类,不捕获他的子类)************************************************************************

class ValueErrorSubclass(ValueError):

pass

class HandleValueError(object):

def __enter__(self):
return self

def __exit__(self, exc_type, exc_val, exc_tb):
if exc_type == ValueError:
return True

return False

with HandleValueError():
pass
# raise ValueErrorSubclass('value error subclass')

# 3.更简单的用法************************************************************************
import contextlib
# @contextlib.contextmanager 装饰简单函数,将函数转换为上下文管理器类

from contextlib import contextmanager

@contextmanager
def file_open(path):
try:
f_obj = open(path,"w")
yield f_obj
except OSError:
print("We had an error!")
finally:
print("Closing file")
f_obj.close()


# with file_open("test.txt") as fobj:
# fobj.write("Testing context managers")

posted @ 2020-07-28 16:42  ~相忘于江湖  阅读(71)  评论(0)    收藏  举报