单例中超类的使用

2 投票
1 回答
728 浏览
提问于 2025-04-17 19:44
class Singleton(object):
  def __new__(cls, *args, **kw):
      if not hasattr(cls, '_instance'):
        orig = super(Singleton, cls)
        cls._instance = orig.__new__(cls, *args, **kw)
      return cls._instance

有没有人能详细解释一下这里发生了什么 >> super(Singleton, cls) 这个 cls 参数是用来干嘛的?

1 个回答

3

在这里,传递给 __new__ 方法的 cls 属性其实是指向 Singleton 类的引用(也就是说 cls == Singleton)。不过,如果你创建了一个 Singleton 的子类,并且实例化了这个子类,那么 cls 就会指向这个子类。

super 需要知道当前的类(Singleton)和它正在遍历的子类(cls),这样才能计算出类的继承关系中的下一个类。但在你的情况中,它们总是相同的,因为 Singleton 没有任何子类。

为了更好地理解为什么需要传递 cls,我们假设这些类都有简单的 __new__ 方法,这些方法只是调用它们的父类方法并返回结果。

class A(object): pass
class B(object): pass
class C(A, B): pass

然后 C.__new__ 调用 super(C, cls).__new__,这相当于 A.__new__。在这里,你希望 super(A, cls).__new__ 等于 B.__new__,而不是 object.__new__。但 super 只有在被告知起始点是 C 而不是 A 的情况下,才能找到这个信息。

因为在你的情况下,唯一的父类是 object,所以 orig.__new__ 相当于 object.__new__,并且它传递了 cls,这样它就知道应该实例化哪个类。

撰写回答