首页 > 其他 > 详细

基于 __new__ 方法的单例模式

时间:2019-03-01 19:56:31      阅读:165      评论:0      收藏:0      [点我收藏+]

 单例模式定义

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

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

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

 

基于 __new__ 方法的单例模式

原文:https://www.cnblogs.com/shijieli/p/10458305.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!