关于类的__new__方法
class Singletion:def __new__(cls, *args, **kwargs):
if not hasattr(cls, "_instance"):
cls._instance = super(Singletion, cls).__new__(cls)
return cls._instance
class MyClass(Singletion):
def __init__(self, a):
self.a = a
a = MyClass(10)
b = MyClass(20)
print(a.a)
print(b.a)
1.请问第4行的cls._instance = super(Singletion, cls).__new__(cls)这个语法怎么理解
(尤其是super里面的参数){:5_92:}
2.请大佬给我详细讲解这个代码的运行逻辑 本帖最后由 阿奇_o 于 2021-11-8 01:31 编辑
首先,假设你已经大概理解了"单例模式", 和 hasattr() 的作用,
那么,关键难点就是理解: super()的本质 (建议先研究一下:https://blog.csdn.net/zhangjg_blog/article/details/83033210)
如果你在cls._instance前一行,print(super(Singleton, cls)) 就会发现有意思的东西……<super: <class 'Singleton'>, <MyClass object>>
简而言之,cls._instance = super(Singleton, cls).__new__(cls)
# 利用super()返回的super对象(特殊查找顺序),最后用到的__new__()方法,其实是MyClass的 默认的__new__(),所以 其创建和返回了 一个 MyClass的实例对象。
注:cls 类似 self ,代表该类的一个对象。
代码参考:
class Singleton:
def __new__(cls, *args, **kwargs):
if not hasattr(cls, "_instance"):
# print(super(Singleton, cls))# 理解super与super()的本质:
cls._instance = super(Singleton, cls).__new__(cls)
# 利用super()返回的super对象(特殊查找顺序),最后用到的__new__()方法,其实是MyClass的(默认的__new__())
# cls._instance = super().__new__(cls)# Python3的优化(简写)
return cls._instance
# class MyClass(): # 普通的类(非单例模式)
class MyClass(Singleton):# 继承"单例父类"(从而使它具有单例模式的作用)
def __init__(self, value):
self.val = value
a = MyClass(10)# 创建单一实例,其val属性值为10
b = MyClass(20)# 单例模式下,单一实例的val属性值 将被修改(10-->20)
print(a.val)# 20 ? 为什么? 因为"单列模式"下,只存在一个实例对象,该对象的属性"共用"
print(b.val)# 20
补充:
因为MyClass继承了Singleton,故a = MyClass(10)时,先会创建父类Singleton的对象。又因为在Singleton父类的__new__中遇到super(),便根据super的查找顺序,
找到了MyClass的__new__() ,最终创建和返回了 一个 MyClass的实例对象,并与变量名"_instance" 进行绑定。最后返回该实例给到__init__,从而完成初始化。
而 当 b = MyClass(20)时,因为此时cls(MyClass的一个实例)已经存在绑定好的_instance,
父类Singleton的__new__()就不再执行创建实例了,而是 共用第一次所创建的_instance实例 —— 这也是"单列模式"说要达到效果。
页:
[1]