单例模式定义
首次实例化创建实例化对象
之后的每次实例化都用最初的实例化对象 即单实例模式
__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 属性 """