测开学习-进阶函数--魔术方法call() 和上下文管理器协议

练习题

“”"
1、通过装饰器实现单例模式,只要任意一个类使用该装饰器装饰,
那么就会变成一个单例模式的类。(面试真题)

2、为第一次课创建的DB类,实现上下文管理器协议,实现退出上下文时,自动关闭游标,断开连接
“”"

第一道题

解题思路:先定义一个类作为装饰器,并且 定义 构造方法 init(),以及 call() 方法,以便于 被装饰的类函数可正常实例化。并且在__call__()中进行单例判断,若未实例化则进行实例化,已实例化的则直接返回实例化后对象

class Decorator:
    __instance = None

    def __init__(self, func):
        print('===初始化===')
        self.func = func

    def __call__(self, *args, **kwargs):
        print('--------调用方法-------')
        if not self.__instance:
            self.__instance = self.func()
        return self.__instance
        
@Decorator
class demo:
    def __init__(self):
        print('初始化构建demo')
    print('demo')

@Decorator
class demo1:
    def __init__(self):
        print('初始化构建demo1')
    print('demo1')

使用闭包函数作为装饰器的方式

思路是给传入的类对象中进行定义一个类属性,判断该类属性是否为空

def single(cls):
    cls.instance = None
    def wrapper(*args, ** kwargs):
        if not cls.instance:
            cls.instance = cls(*args, **kwargs)
        return cls.instance
    return wrapper

同样思路下 使用类来作为装饰器

class single:
    def __init__(self, cls):
        self.cls = cls
        cls.instance = None

    def __call__(self, *args, **kwargs):
        if not self.cls.instance:
            self.cls.instance = self.cls(*args, **kwargs)
        return self.cls.instance

第二道题

原先的DB类如下:

class DB:
    def __init__(self):
        self.con = pymysql.connect(
            host='127.0.0.1',
            port=3306,
            user='root',
            password='123456',
            database='demo',
            charset='utf8',
            cursorclass=pymysql.cursors.DictCursor,
        )
        self.cur = self.con.cursor()

    def query_sql(self, sql):
        self.cur.execute(sql)
        return self.cur.fetchall()

    def execute_sql(self, sql):
        self.cur.execute(sql)
        return self.con.commit()

    def close(self):
        self.cur.close()
        self.con.close()

解题思路:实现上下文管理协议,重点在于 增加 enter() 以及 exit() 两个函数,以及配合with 故代码如下

@Decorator
class DB:
    def __init__(self):
        self.con = pymysql.connect(
            host='127.0.0.1',
            port=3306,
            user='root',
            password='123456',
            database='demo',
            charset='utf8',
            cursorclass=pymysql.cursors.DictCursor,
        )
        self.cur = self.con.cursor()

    def __enter__(self):
        print('-----enter----')
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        print('------退出前关闭连接和游标--------')
        self.cur.close()
        self.con.close()
        print('---------关闭成功------')

    def query_sql(self, sql):
        self.cur.execute(sql)
        return self.cur.fetchall()

    def execute_sql(self, sql):
        self.cur.execute(sql)
        return self.con.commit()


with DB() as f:
    sql = "select * from student"
    res = f.query_sql(sql)
    print(res)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值