super(子类,类).__ new __(class)做什么?

时间:2018-05-07 10:09:03

标签: python inheritance

Singleton pattern的以下Python实施中:

class Singleton(object):
    def __new__(cls):
        if not hasattr(cls, 'instance'):
            cls.instance = super(Singleton, cls).__new__(cls)
        return cls.instance

cls.instance = super(Singleton, cls).__new__(cls)行有什么作用?

除此之外,我不了解的是super用法。我看到super(subclass, instance)的使用情况,但我们在这里传递了(subclass, class)。那么它会以(Singleton class, Singleton class)作为参数吗?

Live example

1 个答案:

答案 0 :(得分:5)

super()的第二个参数用于两个目的:

  • 提供要搜索的有序类列表;顺序是方法解决顺序(MRO),在super()上搜索属性从名为super()

    的第一个参数的类之后的类开始
  • 将任何描述符(如方法)绑定到。

因此super(clsobject, second_argument)会查找__mro__列表,然后搜索clsobject,然后继续在列表的其余部分搜索您想要的属性。然后,它使用descriptor protocol将对象绑定到second_argument

__new__方法仅对类有意义,因为它创建了一个新实例;调用该方法时还没有实例;它是应该为该类生成实例的工厂。

因此您无法将实例作为第二个参数传递。你只能传入一个类,而super()可以处理它。例如,super()查看type(instance).__mro__,但对于类,则使用classobject.__mro__。所以传递cls在这里完全没问题。

__new__也是静态方法,这意味着它忽略了绑定过程。不会自动传入第一个参数,即类。您需要手动执行此操作,因此...__new__(cls)调用。

所以在这个特定的例子中,行:

cls.instance = super(Singleton, cls).__new__(cls)

将在Singleton中搜索cls.__mro__,找到具有__new__属性的下一个对象,然后尝试将该__new__属性绑定到cls。如果您没有使用多重继承,那将是object.__new____new__方法是静态的,因此不会发生绑定,因此您将获得object.__new__,然后使用cls作为第一个参数进行调用。这将生成Singleton类(或其子类)的实例,然后将其分配给类对象上的属性instance