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)
  • 相关阅读:
    Kubernetes 学习15 kubernetes 认证及serviceaccount
    Kubernetes 学习14 kubernetes statefulset
    Kubernetes 学习13 kubernetes pv pvc configmap 和secret
    Day_13【IO流】扩展案例2_统计指定项目文件中字符出现的次数
    Day_13【IO流】扩展案例1_读取项目文件内容并去重
    Day_12【集合】扩展案例4_判断字符串每一个字符出现的次数
    Day_12【集合】扩展案例3_产生10个长度为10,不能重复,由数字0-9,小写字母和大写字母组成的字符串
    Day_12【集合】扩展案例2_键盘录入一个字符串,对其进行去重,并将去重后的字符串组成新数组
    Day_12【集合】扩展案例1_利用集合的知识对长度为10的int数组进行去重,产生新数组,不能改变数组中原来数字的大小顺序
    Day_11【集合】扩展案例5_对list集合对象中的元素进行反转,求最大值最小值,求元素i在list集合中首次出现的索引,将oldvalue替换为newvalue
  • 原文地址:https://www.cnblogs.com/chvv/p/10138455.html
Copyright © 2011-2022 走看看