# 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)