鱼C论坛

 找回密码
 立即注册
查看: 1124|回复: 1

[已解决]关于类的__new__方法

[复制链接]
发表于 2021-11-7 19:40:00 | 显示全部楼层 |阅读模式
40鱼币
  1. class Singletion:
  2.     def __new__(cls, *args, **kwargs):
  3.         if not hasattr(cls, "_instance"):
  4.             cls._instance = super(Singletion, cls).__new__(cls)
  5.         return cls._instance

  6. class MyClass(Singletion):
  7.     def __init__(self, a):
  8.         self.a = a

  9. a = MyClass(10)
  10. b = MyClass(20)

  11. print(a.a)
  12. print(b.a)
复制代码



1.请问第4行的cls._instance = super(Singletion, cls).__new__(cls)  这个语法怎么理解
(尤其是super里面的参数)
2.请大佬给我详细讲解这个代码的运行逻辑
最佳答案
2021-11-7 19:40:01
本帖最后由 阿奇_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 ,代表该类的一个对象。

代码参考:

  1. class Singleton:
  2.     def __new__(cls, *args, **kwargs):
  3.         if not hasattr(cls, "_instance"):
  4.             # print(super(Singleton, cls))  # 理解super与super()的本质:
  5.             cls._instance = super(Singleton, cls).__new__(cls)
  6.             # 利用super()返回的super对象(特殊查找顺序),最后用到的__new__()方法,其实是MyClass的(默认的__new__())
  7.             # cls._instance = super().__new__(cls)  # Python3的优化(简写)
  8.         return cls._instance

  9. # class MyClass(): # 普通的类(非单例模式)
  10. class MyClass(Singleton):  # 继承"单例父类"(从而使它具有单例模式的作用)
  11.     def __init__(self, value):
  12.         self.val = value

  13. a = MyClass(10)  # 创建单一实例,其val属性值为10
  14. b = MyClass(20)  # 单例模式下,单一实例的val属性值 将被修改(10-->20)

  15. print(a.val)  # 20 ? 为什么? 因为"单列模式"下,只存在一个实例对象,该对象的属性"共用"
  16. 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实例 —— 这也是"单列模式"说要达到效果。

最佳答案

查看完整内容

首先,假设你已经大概理解了"单例模式", 和 hasattr() 的作用, 那么,关键难点就是理解: super()的本质 (建议先研究一下:https://blog.csdn.net/zhangjg_blog/article/details/83033210) 如果你在cls._instance前一行,print(super(Singleton, cls)) 就会发现有意思的东西…… 简而言之,cls._instance = super(Singleton, cls).__new__(cls) # 利用super()返回的super对象(特殊查找顺序),最后用到的__new__() ...
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2021-11-7 19:40:01 | 显示全部楼层    本楼为最佳答案   
本帖最后由 阿奇_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 ,代表该类的一个对象。

代码参考:

  1. class Singleton:
  2.     def __new__(cls, *args, **kwargs):
  3.         if not hasattr(cls, "_instance"):
  4.             # print(super(Singleton, cls))  # 理解super与super()的本质:
  5.             cls._instance = super(Singleton, cls).__new__(cls)
  6.             # 利用super()返回的super对象(特殊查找顺序),最后用到的__new__()方法,其实是MyClass的(默认的__new__())
  7.             # cls._instance = super().__new__(cls)  # Python3的优化(简写)
  8.         return cls._instance

  9. # class MyClass(): # 普通的类(非单例模式)
  10. class MyClass(Singleton):  # 继承"单例父类"(从而使它具有单例模式的作用)
  11.     def __init__(self, value):
  12.         self.val = value

  13. a = MyClass(10)  # 创建单一实例,其val属性值为10
  14. b = MyClass(20)  # 单例模式下,单一实例的val属性值 将被修改(10-->20)

  15. print(a.val)  # 20 ? 为什么? 因为"单列模式"下,只存在一个实例对象,该对象的属性"共用"
  16. 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实例 —— 这也是"单列模式"说要达到效果。

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-5-12 08:28

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表