在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)
作为参数吗?
答案 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
。