首页 > 其他分享 >Day23笔记-Day21和Day22作业讲解&单例类

Day23笔记-Day21和Day22作业讲解&单例类

时间:2024-09-18 18:48:52浏览次数:3  
标签:__ p1 name self Day21 Day23 Day22 instance print

Day22作业讲解

'''
学生类Student:
        属性:学号,姓名,年龄,性别,成绩
​
班级类 Grade:
        属性:班级名称,班级中的学生 【使用列表存储学生】
​
        方法:
            1.查看该班级中的所有学生的信息
            2.查看指定学号的学生信息
            3.查看班级中成绩不及格的学生信息
            4.将班级中的学生按照成绩降序排序
'''
​
class Student():
    __slots__ = ('sid','name','age','score')
    def __init__(self,sid,name,age,score):
        self.sid = sid
        self.name = name
        self.age = age
        self.score = score
    def __repr__(self):
        return f'{self.sid}-{self.name}-{self.score}'
​
class Grade():
    __slots__ = ('grade_name','stus_list')
    def __init__(self,grade_name,stus_list):
        self.grade_name = grade_name
        self.stus_list = stus_list   # 将学生的对象添加到列表中
    def show_all(self):
        print('所有学生的信息如下:')
        for stu in self.stus_list:
            print(stu)  # 调用__init__或__repr__
    def show_single(self,sid):
        print(f'学号为{sid}的学生的信息如下:')
        for stu in self.stus_list:
            if stu.sid == sid:
                print(stu)
                break
        else:
            print('不存在')
    def show_low(self):
        print('不及格学生的信息如下:')
        for stu in self.stus_list:
            if stu.score < 60:
                print(stu)
    def sort_by_score(self):
        print('降序排序之后的信息如下:')
        self.stus_list.sort(reverse=True,key=lambda stu:stu.score)
        self.show_all()
​
if __name__ == '__main__':
    s1 = Student('1003','小明',19,88)
    s2 = Student('1001', '小王', 17, 100)
    s3 = Student('1005', '小李', 19, 56)
    s4 = Student('1006', '小张', 20, 99)
    s5 = Student('1002', '小赵', 18, 60)
​
    grade = Grade('千锋2401',[s1,s2,s3,s4,s5])
    grade.show_all()
    grade.show_single('1006')
    grade.show_low()
    grade.sort_by_score()

一、单例设计模式【重点掌握】

1.概念

什么是设计模式?

​ 设计模式是经过总结、优化的,对我们经常会碰到的一些编程问题的可重用解决方案

​ 设计模式更为高级,它是一种必须在特定情形下实现的一种方法模板。设计模式不会绑定具体的编程语言

​ 23种设计模式,其中比较常用的是单例设计模式,工厂设计模式,代理模式,装饰者模式等等

什么是单例设计模式?

​ 单例:单个实例/单个对象,一个类只能创建一个对象,只能创建出一个对象的类被称为单例类

​ 程序运行过程中,确保某一个类只有一个实例【对象】,不管在哪个模块获取这个类的对象,获取到的都是同一个对象。例如:一个国家只有一个主席,不管他在哪

单例设计模式的核心:一个类有且仅有一个实例,并且这个实例需要应用于整个程序中,该类被称为单例类

问题:验证两个变量中是否存储的是同一个对象

解决:地址

​ 方式一:x1 is x2

​ 方式二:id(x1) == id(x2)

2.应用场景

应用程序中描述当前使用用户对应的类 ———> 当前用户对于该应用程序的操作而言是唯一的——> 所以一般将该对象设计为单例

实际应用:数据库连接池操作 ——> 应用程序中多处地方连接到数据库 ———> 连接数据库时的连接池只需一个就行,没有必要在每个地方都创建一个新的连接池,这种也是浪费资源 ————> 解决方案也是单例

3.实现
3.1实现单例类方式一
# 1.普通类
class Person():
    pass
p1 = Person()
p2 = Person()
print(p1 is p2)  # False
print(id(p1) == id(p2))  # Flase
​
print('*' * 50)
​
# 2.单例类
'''
__new__
__init__
'''
class Person():
    # 定义一个类属性,用于表示当前类可以创建的唯一的对象
    # 因为此类属性无需在类的外面被访问修改,则设置为私有属性
    __instance = None
    def __new__(cls, *args, **kwargs):
        print('new~~~')
        # 只要super().__new__(cls)被执行一次,则会创建出一个新的对象
        # 判断__instance的值,如果为None,则重新赋值为对象并返回,如果非空则直接返回
        if not cls.__instance:
            print('if~~~~')
            cls.__instance = super().__new__(cls)
        return cls.__instance
​
    def __init__(self,name,age):
        print('init~~~~',name,age)
        self.name = name
        self.age = age
p1 = Person('张三',10)  # 创建对象
p2 = Person('李四',20)   # 获取第一次创建的对象,此处的李四和20相当于给对象的name和age属性重新赋值
print(p1 is p2)  # True
print(id(p1) == id(p2))   # True
​
print(p1.name,p2.name)   # 李四
​
p1.name = 'Jack'
print(p1.name,p2.name)
3.2装饰器装饰类
.装饰器装饰类
def wrapper(cls):  # cls表示需要被装饰的类
    def inner(*args,**kwargs):
        c = cls(*args,**kwargs)      # 类(),创建对象:调用类中的构造函数__new__,__init__,所以此处的参数需要和__init__中的参数保持一致
        print('new~~~')  # 新增的功能
        return c
    return inner
​
@wrapper            # 调用外部函数wrapper
class A():
    def __init__(self,name,age):
        self.name = name
        self.age = age
print(A)   # <function wrapper.<locals>.inner at 0x000001DF7EDCC430>
a1 = A('111',10)        # 调用inner,a1中存储的是inner的返回值,为了符合最初创建对象的语法,则给inner设置返回值
print(a1)
3.3实现单例类方式二
def singleton(cls):
    # 定义一个函数作用域的变量,用于存储被装饰的类可以创建的唯一的对象
    instance = None
    def get_instance(*args,**kwargs):
        nonlocal instance
        if not instance:
            instance = cls(*args, **kwargs)  # 调用__init__
        return instance
    return get_instance
​
@singleton
class Person():
    def __init__(self,name,age):
        print('init~~~~~',name,age)
        self.name = name
        self.age = age
​
p1 = Person('张三',10)   # 调用get_instance
p2 = Person('李四',20)   # 调用get_instance
print(p1 is p2)  # True
print(id(p1) == id(p2))  # True
​
print(p1.name,p2.name)   # 张三
​
p1.name = 'Jack'
print(p1.name,p2.name)
3.4实现单例类方式三
def singleton(cls):
    # 定义一个函数作用域的字典变量,key:被装饰的类,value:唯一的对象
    instance = {}
    def get_instance(*args,**kwargs):
        if not instance:
            # 向字典中添加键值对
            instance[cls] = cls(*args, **kwargs)  # 调用__init__
        return instance[cls]
    return get_instance
​
@singleton
class Person():
    def __init__(self,name,age):
        print('init~~~~~',name,age)
        self.name = name
        self.age = age
​
p1 = Person('张三',10)   # 调用get_instance
p2 = Person('李四',20)   # 调用get_instance
print(p1 is p2)  # True
print(id(p1) == id(p2))  # True
​
print(p1.name,p2.name)   # 张三
​
p1.name = 'Jack'
print(p1.name,p2.name)  

标签:__,p1,name,self,Day21,Day23,Day22,instance,print
From: https://blog.csdn.net/m0_61388098/article/details/142340917

相关文章

  • Day21笔记-封装&继承
    复习面向对象基础语法#定义类classPerson():  #类属性  num=10  #限制对象属性的动态绑定  __slots__=('name','age','hobby')  #定义实例属性  def__init__(self,name,age,hobby):    self.name=name    self......
  • day21
    非递减子序列classSolution{public:voidbacktracking(vector&nums,intstart){if(path.size()>1){ret.push_back(path);}if(start==nums.size()){return;}unordered_setuset;for(inti=start;i<nums.size();++i){if((!path.empty()&......
  • 代码训练营 Day23| 39. 组合总和 |40.组合总和II |131.分割回文串
    39.组合总和1.组合没有数量要求2.元素可无限重复选取classSolution(object):defbacktracking(self,cadinates,target,sum_,startindex,path,result):#recursionstopconditionifsum_>target:#wecan'tfindanyanswerset......
  • NOIP2024集训Day23 DP常见模型3 - 树形
    NOIP2024集训Day23DP常见模型3-树形A.[CSP-S2021]括号序列区间dp,令\(f_{l,r}\)表示从位置\(l\)到位置\(r\)一共的合法序列总情况数量。一共有六种不同的转移情况,所以将\(f_{l,r}\)扩充到三维。全是*(...)(...)**(...)***,左边以括号序列开头,右边以*结尾......
  • NOIP2024集训Day21 DP常见模型2 - 背包
    NOIP2024集训Day21DP常见模型2-背包A.[BZOJ4987]Tree树形背包dp先考虑几个显而易见的性质:选出的点一定是相邻的对于选出的点,如果从\(a_k\)再走回\(a_1\),那么就相当于每条边经过了两次由于题目没有包含\(dis(a_k,a_1)\),因此就相当于选出的点中的一条链可以只......
  • NOIP2024集训Day22 DP常见模型3 - 区间
    NOIP2024集训Day22DP常见模型3-区间A.[SCOI2003]字符串折叠因为前面折叠了会对后面产生影响,所以很显然不能贪心。考虑区间DP。定义\(f_{i,j}\)表示\(i\)到\(j\)范围内可以折叠到的最短长度。答案为\(f_{1,n}\)。状态转移:对于\(f_{i,j}\),使用区间DP惯用套路,枚......
  • 枚举 day22
    枚举类型是Java中一种用于统一管理有限的常量数据的数据类型。它将常量设置为对象,提高了代码的可读性和简洁性。通过使用枚举类型,可以在代码中更方便地读取和使用常量。packagecom.shujia.day22;/*1.创建枚举类的属性(成员变量),必须是作为私有常量出现2.必须......
  • 代码随想录DAY22 - 回溯算法 - 08/21
    目录理论回顾什么是回溯法回溯法的效率回溯法解决的问题如何理解回溯组合题干思路和代码递归法递归优化:剪枝组合总和Ⅲ题干思路和代码递归法递归优化电话号码的字母组合题干思路和代码递归法理论回顾什么是回溯法回溯是一种类似枚举的搜索方法,回溯和......
  • 代码随想录DAY23 - 回溯算法 - 08/22
    组合总和题干题目:给你一个无重复元素的整数数组candidates和一个目标整数target,找出candidates中可以使数字和为目标数target的所有不同组合,并以列表形式返回。你可以按任意顺序返回这些组合。candidates中的同一个数字可以无限制重复被选取。如果至少......
  • 代码随想录Day23
    131.分割回文串给你一个字符串s,请你将s分割成一些子串,使每个子串都是回文串。返回s所有可能的分割方案。示例1:输入:s="aab"输出:[["a","a","b"],["aa","b"]]示例2:输入:s="a"输出:[["a"]]提示:1<=s.length<=16s仅由......