• 基于 __new__ 方法的单例模式


     单例模式定义

    首次实例化创建实例化对象

    之后的每次实例化都用最初的实例化对象 即单实例模式

    __new__ 的原理

    __new__ 方法可以在 __init__ 方法执行 

    这样可以在初始化之前进行一系列的其他操作

    比如在这里创建一个全局实例

    实现代码

    class A:
        __instance = False  # 定义一个私有的变量,只能内部的去拿
    
        def __init__(self, name, age):
            self.name = name
            self.age = age
    
        def __new__(cls, *args, **kwargs):
            if cls.__instance:  # 第一次循环外部拿不到自然就是 False
                return cls.__instance
            else:
                # cls.__instance = object.__new__(A)  # 借助object类创建的实例并赋值
                cls.__instance = super().__new__(A)  # 当然也可以借助 super 方法
    
                return cls.__instance

    关于使用父类方法的时候, super 方法是很好用的选择. 3.0版本中super 使用更加简单

    代码分析

    第一次创建的__instance变量一定是 false 的
        因此必然返回一个借助 object 类创建的实例并赋值
        所创建的这个实例是什么都没有的,没有self的属性,只是开辟了一段空的内存地址给他用
    之后在调用 __init__ 根据你的参数赋值属性添加内存
    
    __instance 是保存在类里面的静态变量
    
    以后每次进来都是使用 cls.__instance 作为实例了

    测试结果

    a = A("a", 2)
    a.cloth = "女装"
    b = A("b", 2)

     测试单例

    print(b)
    print(a)
    """
    <__main__.A object at 0x000000000255D208>
    <__main__.A object at 0x000000000255D208>
    """
    结果

    测试实例属性覆盖

    print(a.name)
    print(b.name)
    """
    # 在创建示例会覆盖之前的实例的属性,但是两个示例都是存在的
    b
    b      # name 和age 都会被下一次实例化的时候被新值锁覆盖
    """
    结果

     测试实例额外属性

    print(a.cloth)
    print(b.cloth)
    """
    none        # 尽管使用一个内存地址但是cloth 的属性没有被覆盖,而且保存在地址里面也不会被清除
    none        # sb示例并没有创建 cloth 属性,但是依然可以调用出来之前 suyang 示例的属性 ,即继承了之前的属性
    """
    结果

    测试实例属性覆盖

    b.hobby = "bb"
    print(a.hobby)
    """
    bb          # 相同的没有创建 hobby 的 suyang 示例 也可以继承之后的 sb 创建的 hobby 属性
    """
    结果

    全部代码

    class A:
        __instance = False  # 定义一个私有的变量,只能内部的去拿
    
        def __init__(self, name, age):
            self.name = name
            self.age = age
    
        def __new__(cls, *args, **kwargs):
            if cls.__instance:  # 第一次循环外部拿不到自然就是 False
                return cls.__instance
            else:
                # cls.__instance = object.__new__(A)  # 借助object类创建的实例并赋值
                cls.__instance = super().__new__(A)  # 当然也可以借助 super 方法
    
                return cls.__instance
    
    
    """
    第一次创建的__instance变量一定是 false 的
        因此必然返回一个借助 object 类创建的实例并赋值
        所创建的这个实例是什么都没有的,没有self的属性,只是开辟了一段空的内存地址给他用
    之后在调用 __init__ 根据你的参数赋值属性添加内存
    
    __instance 是保存在类里面的静态变量
    
    以后每次进来都是使用 cls.__instance 作为实例了
    """
    
    a = A("a", 2)
    a.cloth = "女装"
    b = A("b", 2)
    
    print(b)
    print(a)
    """
    <__main__.A object at 0x000000000255D208>
    <__main__.A object at 0x000000000255D208>
    """
    
    print(a.name)
    print(b.name)
    """
    # 在创建示例会覆盖之前的实例的属性,但是两个示例都是存在的
    b
    b      # name 和age 都会被下一次实例化的时候被新值锁覆盖
    """
    
    print(a.cloth)
    print(b.cloth)
    """
    none        # 尽管使用一个内存地址但是cloth 的属性没有被覆盖,而且保存在地址里面也不会被清除
    none        # sb示例并没有创建 cloth 属性,但是依然可以调用出来之前 suyang 示例的属性 ,即继承了之前的属性
    """
    
    b.hobby = "bb"
    print(a.hobby)
    """
    bb          # 相同的没有创建 hobby 的 suyang 示例 也可以继承之后的 sb 创建的 hobby 属性
    """
    全部代码
  • 相关阅读:
    56. Merge Intervals
    Reorder List
    Merge Two Sorted Lists
    彻底删除kafka topic数据
    什么时候类加载
    checkpoint的作用
    case when
    SQL:将查询结果插入到另一个表的三种情况
    IFNULL函数
    kafka主要配置
  • 原文地址:https://www.cnblogs.com/shijieli/p/10458305.html
Copyright © 2020-2023  润新知