基于 __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 属性
"""
全部代码

猜你喜欢

转载自www.cnblogs.com/shijieli/p/10458305.html