设计模式--单例模式的多种实现方法与pickle 模块

设计模式

在IT行业中一共有23种设计模块,主要分为三大类型
1、创建类型
2、结构类型
3、行为类型

"""设计模块是前辈们发明的经过反复的验证用来解决固定问题的固定套路"""
我们目前需要掌握的是创建型中的 单例模式


单例模式的多种方式

单例模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建
主要场景:
	一个类里有很多牛逼的方法绑定给对象,我们可能在很多地方都要使用它,每次使用都要产生一个新的类,占据了内存空间,所以使用单例模式  

基于@classmethod实现:

class C1:
    __instance = None

    def __init__(self, name, age):
        self.name = name
        self.age = age

    @classmethod  # 绑定给类的方法,会把类当做参数传入
    def singletoh(cls):
        # 用类.__instance 判断值是否不为空
        if not cls.__instance:
            # 不为空则 手动生成对象并赋值给 __instance
            cls.__instance = cls('tank', 18)
        # 返回对象
        return cls.__instance


obj1 = C1.singletoh()
obj2 = C1.singletoh()
print(id(obj1), id(obj2))
print(obj1.__dict__,obj2.__dict__)

基于装饰器实现:

def singleton(cls):
    '''
      cls:表示一个类名,即所要设计的单例类名称,
          因为python一切皆对象,故而类名同样可以作为参数传递
      '''
    instance = {}

    def singleton(*args, **kwargs):  # 4.接受singleton('tank', 18)  args = (tank,18)
        if cls not in instance:    # 5. 判断类是否不在字典内
            instance[cls] = cls(*args, **kwargs)  # 6,如果没有cls这个类,先看赋值符号右侧 则调用类,到类里执行__init  # 10,此时 self.name = tank ,self.age = 18 赋值给字典里
        return instance[cls]  # 11.返回字典键 所对应的对象
    # 2. 返回 singleton 函数 给 Student
    return singleton


@singleton
class Student:  # 1.语法糖将Student 当作参数传入外层
    def __init__(self, name, age):  # 7. 接受args 参数 tank   18
        self.name = name  # 8   name = tank
        self.age = age  # 9.  age =18


s1 = Student('tank', 18)  # 3.此时Student('tank', 18) 等于返回的 singleton('tank', 18)  # 12.接收对象
s2 = Student('tony', 18)  
print((s1 == s2))
print(s1 is s2)
print(s1.__dict__,s2.__dict__)

基于双下new实现:

class Student(object):
    instance = None

    def __new__(cls, name, age):
        if not cls.instance:
            cls.instance = super().__new__(cls)
        return cls.instance

    def __init__(self, name, age):
        self.name = name
        self.age = age

s1 = Student('tank', 23)
s2 = Student('tony', 24)
print((s1 == s2))
print(s1 is s2)

使用一个单独的模块来实现:

在一个模块中定义一个普通的类,如在demo.py模块中定义如下代码
  md.py
  class Student:
      def __init__(self,name,age):
          self.name=name
          self.age=age
   
  student=Student('tony',23)

  这里的student就是一个单例。 当我们在另外一个模块中导入student这个对象时,因为它只被导入了一
次,所以总是同一个实例。
  #test.py
  from demo import student
  #此时,无论该test脚本怎么运行,import进来的student实例是唯一的

pickle序列化模块

实操:
将对象保存到文件,并且取出来自后还可以在使用对象的功能

import pickle
class MyClass(object):
    school = 'school'
    def __init__(self, name):
        self.name = name
    def choose_course(self):
        print('%s正在选课'%self.name)
obj = MyClass('tank')
print(obj.school)
obj.choose_course()
# 存对象
# 使用二进制模式
with open(r'%s'% obj.name, 'wb') as f:
    pickle.dump(obj, f)
# 取对象
with open(r'%s'% obj.name, 'rb') as f:
    date = pickle.load(f)
    
""" 该模块只支持python """
posted @ 2022-11-09 17:28  李阿鸡  阅读(33)  评论(0编辑  收藏  举报
Title