简单单例实现中的super(类型,子类)

时间:2014-06-12 21:09:51

标签: python

当我在python中实现naive singleton时,我想出了一个超级关键词的问题。像往常一样,超级的行为总是棘手和错误,希望有人可以阐明它。谢谢:))

问题在于:

class Singleton(object):
    def __new__(cls,*args,**kw):
        if not hasattr(cls,'_instance'):
            #create a instance of type cls,
            origin=super(Singleton,Singleton).__new__(cls,*args,**kw)
            cls._instance=origin
        return cls._instance

class B(Singleton):
    def __init__(self,b):
        self.b=b

它确实有效,但我想知道

如果我将第5行更改为下面的内容会更好吗?

origin=super(Singleton,cls).__new__(cls,*args,**ks)

有什么不同之处?

1 个答案:

答案 0 :(得分:1)

super()在当前对象的MRO中搜索具有所请求属性的下一个类。 super()的第一个参数确定了MRO搜索的起点,第二个参数确定了从中获取MRO的对象。

只要您不使用多重继承,您的MRO就会很简单。在这种情况下,Singleton将始终位于MRO中的相同位置。使用多重继承,子类的MRO中出现Singleton的地方会有所不同,您真的想使用cls来获取当前 MRO,而不是{MRO> { {1}}。

对于您的简单示例,忽略Singleton(例如cls)就可以了:

B

因此,>>> class Singleton(object): ... def __new__(cls,*args,**kw): ... if not hasattr(cls,'_instance'): ... #create a instance of type cls, ... origin=super(Singleton,Singleton).__new__(cls,*args,**kw) ... cls._instance=origin ... return cls._instance ... >>> class B(Singleton): ... def __init__(self,b): ... self.b=b ... >>> B.__mro__ (<class '__main__.B'>, <class '__main__.Singleton'>, <type 'object'>) >>> Singleton.__mro__ (<class '__main__.Singleton'>, <type 'object'>) super(Singleton, Singleton)最终会搜索相同的子列表,仅查找super(Singleton, cls)

然而,使用多重继承,您将获得一个非常不同的 MRO;请注意,objectFoo之间列出了Singleton

object

如果您使用>>> class Foo(object): pass ... >>> class Bar(Singleton, Foo): pass ... >>> Bar.__mro__ (<class '__main__.Bar'>, <class '__main__.Singleton'>, <class '__main__.Foo'>, <type 'object'>) ,那么在查找继承的方法时,super(Singleton, Singleton)会无意中跳过 Foo将搜索super(Singleton, cls)(Foo, object)只会查看super(Singleton, Singleton)