当我在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)
有什么不同之处?
答案 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;请注意,object
和Foo
之间列出了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)
。