设计模式和单例模式__new__方法

# 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)
原文地址:https://www.cnblogs.com/chvv/p/10138455.html