__new__方法实现单例模式中,super()的用法

写一个简单的打开文件进行日志记录的单例模式
class Logger:
    __instance = None

    def __new__(cls, *args, **kwargs):
        if not cls.__instance:
            cls.__instance = super().__new__(cls)
            cls.__instance.logfile = open("log.txt", "a")
        return cls.__instance

    def log_write(self, message):
        self.logfile.write(message + "\n")


log1 = Logger()
log2 = Logger()
log1.log_write("this is a log file and this is start write.")
print(id(log1))  # 1763310177392
print(id(log2))  # 1763310177392
print("log function result is ", log2 is log1)     # log function result is  True

### 分析下面单例模式中的代码
class Test__new2(object):
__instance = None

def __new__(cls, *args, **kwargs):
    if not cls.__instance:
        # cls.__instance = object.__new__(cls)  # 调用父类的__new__方法来创建实例,这个更简洁
        cls.__instance = super(Test__new2, cls).__new__(cls)   # 和上面一行的作用相同,调用父类的__new__方法来创建实例,这个可以指定父类
    return cls.__instance
te1 = Test__new2()
上面代码中super方法为什么传Test__new2, cls参数,解释一下super的用法


在你的代码中,super(Test__new2, cls).__new__(cls) 这一行的 super 用法涉及到 Python 的类继承机制和方法解析顺序。让我们深入分析一下。
super 的基本用法
super() 是 Python 中的一个内置函数,它用于调用父类(或者称为基类)的方法,通常用于多重继承中,帮助你明确调用某个类的父类的方法。super() 的常见语法是:
super([type], [object-or-type])


1.type:指定类,表示从哪个类开始搜索父类。
2.object-or-type:指定对象实例,表示从哪个类的实例开始搜索父类。

在你提供的代码中,super(Test__new2, cls) 表示从 Test__new2 类的父类开始搜索方法,而 cls 是当前的类(在此是 Test__new2),
因此 super(Test__new2, cls) 会从 Test__new2 的父类(即 object 类)开始查找方法。
super(Test__new2, cls).__new__(cls) 具体含义
super(Test__new2, cls) 这一部分是通过 super() 让 Test__new2 的类向上查找其父类的方法。在这里,
它告诉 Python 从 Test__new2 类的父类开始,找到该父类的 __new__ 方法,并调用它。

3.Test__new2 类:当前类,在实例化时调用 __new__ 方法。
4.cls:当前类的类对象,在 __new__ 方法中,它指向 Test__new2 类。cls 是 Python 中类方法(包括 __new__)的隐式参数,它指向当前调用该方法的类。

在 super(Test__new2, cls) 中,Test__new2 是我们传给 super() 的类,cls 是当前类的类对象(在本例中是 Test__new2)。
这段代码的含义是:从 Test__new2 类的父类(即 object 类)开始查找 __new__ 方法,并调用它。
为什么要传 Test__new2 和 cls?
在 Python 中的单继承或多重继承时,super() 的目的是帮助我们从父类调用方法。对于 Test__new2 类,父类是 object 类,而 cls 表示当前类的类对象。
当你传递 Test__new2 和 cls 给 super() 时,目的是确保 super() 方法能够在正确的继承链中找到父类并调用。
解释 super(Test__new2, cls).__new__(cls):

5.super(Test__new2, cls) 表示从 Test__new2 的父类(object)开始查找。
6.__new__(cls) 调用父类的 __new__ 方法,并将 cls 作为参数传入。这个 cls 指向当前类(在此是 Test__new2),而 __new__ 方法最终会返回一个新实例。

super() 在单继承和多继承中的作用:
在单继承中,super() 比直接调用父类方法更灵活,因为它遵循方法解析顺序(MRO,Method Resolution Order)。
MRO 定义了方法查找的顺序,尤其在涉及多继承时,super() 有助于避免重复调用同一个父类的方法。
总结:
在你的代码中,super(Test__new2, cls).__new__(cls) 这行代码通过 super() 方法来调用 Test__new2 类的父类(object 类)的 __new__ 方法。
传入 Test__new2 和 cls 参数的原因是:

7.Test__new2 指定了要查找的父类。
8.cls 指定了当前调用方法的类对象,它的作用是在方法解析过程中找到正确的位置。

因此,super(Test__new2, cls) 让你能够调用 object 类的 __new__ 方法,从而实现实例的创建。

posted @ 2025-09-04 10:34  大海一个人听  阅读(12)  评论(0)    收藏  举报