前文课题
通过装饰器来实现单例模式
通过类实现一个通用装饰器,皆可以装饰函数也可装饰类,即可有参也可无参
描述 new str repr call 分别会在什么时候被触发
new 创建实例对象的时候
str print实例对象的时候,str处理对象的时候,format处理对象的时候
repr 调用repr方法的时候
call 对象被调用的时候会触发
上下文管理器
思考一个问题,python中,with打开文件为什么会自动关闭,是怎么实现的
with关键字后面跟着的事一个上下文管理对象
上下文管理器的概念:
上下文管理器是一个python对象,为操作提供了额外的上下文信息,这种额外的信息,在使用with语句初始化上下文,以及完成with块中的所有代码时,采用可调用的形式
上下文管理器的实现:
如果要自己实现上下文管理器,首先要知道上下文管理协议。
简单来说,就是要在一个类里面实现enter和exit方法,这个类的实例就是一个上下文管理器。
在本例中,运行没有抛出异常,就是因为使用了上下文管理器,异常可以在exit进行捕获并且由编写者决定如何处理,是抛出还是在此就解决了,而在exit方法内部返回true(没有return则默认为false),相当于告诉python,这个异常已经捕获了,不需要再向外抛了。
写exit函数时,需要注意,必须有三个参数:
exc_type 异常类型,exc_val 异常值 , exc_tb 异常的错误栈信息,也就是异常回溯信息。
而当代码没有异报异常的时候,三个参数都为None
观察执行可以看出,在编写代码的时候可以将资源的连接或者获取放在 __enter__中,将资源的关闭卸载放在__exit__中。
看一个实际应用: 需求 ,利用上下文管理器编写一个连接DB返回游标的类。
# 实现一个操作mysql的上下文管理器,可以自动断开连接
import pymysql class DB: def __init__(self, **data_conf): # 初始化db , self.conn = pymysql.connect(**data_conf) self.cursor = self.con.cursor() def __enter__(self): # 将游标返回到上下文中 return self.cursor def __exit__(self, exc_type, exc_val, exc_tb): self.cursor.close() self.conn.close() # 以元祖格式书写,直接强转成dict DB_conf = dict( host='localhost', user='root', password='123456', port=3306, charset='utf8' ) print(type(DB_conf)) print(DB_conf) # with 后面跟的是一个函数主题,也可以是自定义的类 with DB(DB_conf) as cur: # cur 作为enter方法返回的上下文句柄,是db的游标 cur.execute('sql') print(cur.fetchone()) # 描述slots属性的作用,并修改读取excel类中保存用例的类 # 限制对象属性,指定指定的slots的属性 # 节约内存 class Case: __slots__ = ['case_id','title','url','data'] def __int__(self): self.case_id = None self.title = None self.url = None self.data = None