# 01. 单例设计模式 # # 设计模式 # 设计模式 是 前人工作的总结和提炼,通常,被人们广泛流传的设计模式都是针对 某一特定问题 的成熟的解决方案 # 使用 设计模式 是为了可重用代码、让代码更容易被他人理解、保证代码可靠性 # # 单例设计模式 # 目的 —— 让 类 创建的对象,在系统中 只有 唯一的一个实例 # 每一次执行 类名() 返回的对象,内存地址是相同的 # 02. __new__ 方法 # # 使用 类名() 创建对象时,Python 的解释器 首先 会 调用 __new__ 方法为对象 分配空间 # __new__ 是一个 由 object 基类提供的 内置的静态方法,主要作用有两个: # 1) 在内存中为对象 分配空间 # 2) 返回 对象的引用 # Python 的解释器获得对象的 引用 后,将引用作为 第一个参数,传递给 __init__ 方法 # # 重写 __new__ 方法 的代码非常固定! # # 重写 __new__ 方法 一定要 return super().__new__(cls) # 否则 Python 的解释器 得不到 分配了空间的 对象引用,就不会调用对象的初始化方法 # 注意:__new__ 是一个静态方法,在调用时需要 主动传递 cls 参数 # 单例模式 # 一个类 始终 只有 一个 实例 # 当你第一次实例化这个类的时候 就创建一个实例化的对象 # 当你之后再来实例化的时候 就用之前创建的对象,新值会覆盖原来的值,没有重写的不会覆盖,还会显示原来的值 #如果之前已经创建过一个对象了,再次创建对象就用之前的对象,新值会覆盖原来的值,没有重写的不会覆盖,还会显示原来的值 class A: __instance = False def __init__(self,name,age): self.name = name self.age = age def __new__(cls, *args, **kwargs): print(cls.__instance) #第一次实例化对象的时候值为False if cls.__instance: print("====") #第二次实例化的时候有值 print(cls.__instance) return cls.__instance #第一次实例化对象的时候值为False,执行父类的__new__方法 print(object.__new__(cls)) print("--------") cls.__instance = object.__new__(cls) return cls.__instance, egon = A('egg',38) #第一次实例化的时候 # False # <__main__.A object at 0x0000020C5726BF60> # -------- # <__main__.B object at 0x0000020C5726BFD0> egon.cloth = '小花袄' print("********") nezha = A('nazha',25) # 第二次实例化的时候'nazha',25,把'egg',38覆盖了 # 第二次实例话的结果 # <__main__.A object at 0x000002763A11BFD0> # ==== # <__main__.A object at 0x000002763A11BFD0> # <__main__.B object at 0x000002763A1240B8> print("$$$$$$$$$$$") print(nezha) #<__main__.A object at 0x000001E06435BFD0> print(egon) #<__main__.A object at 0x000001E06435BFD0> print(nezha.name)#nazha print(nezha.age) print(egon.name)#nazha print(nezha.cloth)#'小花袄'cloth没有被替换,还用原来的值 class A: def __init__(self,name): self.name = name def __eq__(self, other): if self.__dict__ == other.__dict__: return True else: return False #判断两个对象是否相等 ob1 = A('egon') ob2 = A('egg') ob3 = A('egg') print(ob1 == ob2) #False print(ob2 == ob3) #True # hash() #__hash__ class A: def __init__(self,name,sex): self.name = name self.sex = sex def __hash__(self): return hash(self.name+self.sex) a = A('egon','男') b = A('egon','nv') print(hash(a)) print(hash(b))
class Foo(object): __instance = None def __new__(cls, *args, **kwargs): # 这里不能使用__init__,因为__init__是在instance已经生成以后才去调用的 if cls.__instance is None: ##如果为None, print("====") print(cls.__instance) cls.__instance = super(Foo, cls).__new__(cls, *args, **kwargs) return cls.__instance s1 = Foo() s2 = Foo() print(s1) print(s2)
class Test1(object): __obj = None def __new__(cls, *args, **kwargs): # 这里不能使用__init__,因为__init__是在instance已经生成以后才去调用的 if cls.__obj == None: #如果为None,即第一次创建对象 print(cls.__obj) #None print(not cls.__obj) #True cls.__obj = object.__new__(cls,*args,**kwargs) #创建对象 print(cls.__obj) #<__main__.Test1 object at 0x03B716D0> print(not cls.__obj) #False return cls.__obj #返回对象 下次再调用的时候cls.__obj不为None,直接返回当前cls.__obj s1 = Test1() s2 = Test1() print (s1) print(s2)
class Test1(object): __obj = None def __new__(cls, *args, **kwargs): # 这里不能使用__init__,因为__init__是在instance已经生成以后才去调用的 if cls.__obj == None: #如果为None,即第一次创建对象 cls.__obj = object.__new__(cls,*args,**kwargs) #创建对象 return cls.__obj #返回对象 下次再调用的时候cls.__obj不为None,直接返回当前cls.__obj s1 = Test1() s2 = Test1() print (s1) print(s2)
"""装饰器单例模式""" def single(cls,*args,**kwargs): instance = {} #创建一个字典 def get_instance(*args,**kwargs): if cls not in instance: instance[cls] = cls(*args,**kwargs) # 判断instances字典中是否含有单例,如果没有就创建单例并保存到instances字典中,然后返回该单例 return instance[cls] #返回cls(*args,**kwargs) return get_instance #返回get_instance @single class Student(): def __init__(self, name, age): self.name = name self.age = age st1 = Student('aa',18) st2 = Student('bb',21) print("===") print(s1) print(s2)