zoukankan      html  css  js  c++  java
  • 设计模式和单例模式__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)
  • 相关阅读:
    leetcode 13. Roman to Integer
    python 判断是否为有效域名
    leetcode 169. Majority Element
    leetcode 733. Flood Fill
    最大信息系数——检测变量之间非线性相关性
    leetcode 453. Minimum Moves to Equal Array Elements
    leetcode 492. Construct the Rectangle
    leetcode 598. Range Addition II
    leetcode 349. Intersection of Two Arrays
    leetcode 171. Excel Sheet Column Number
  • 原文地址:https://www.cnblogs.com/chvv/p/10138455.html
Copyright © 2011-2022 走看看