如何理解`org = super(Singleton,cls)`和`org .__ new __(cls,* args,** kw)`?

时间:2018-07-06 03:05:08

标签: python

如何理解此代码:

我正在研究Python的Singleton实现:

class Singleton(object):
    ''''' A python style singleton '''

    def __new__(cls, *args, **kw):
        if not hasattr(cls, '_instance'):
            org = super(Singleton, cls)  # what does this line mean, what's the funciton of it?  
            cls._instance = org.__new__(cls, *args, **kw) # and this line
        return cls._instance


if __name__ == '__main__':
    class SingleSpam(Singleton):
        def __init__(self, s):
            self.s = s

        def __str__(self):
            return self.s


    s1 = SingleSpam('spam')
    print id(s1), s1
    s2 = SingleSpam('spa')
    print id(s2), s2
    print id(s1), s1

我不明白这两行代码:

org = super(Singleton, cls)  
cls._instance = org.__new__(cls, *args, **kw) 
  1. cls是否等于self
  2. org = super(Singleton, cls)是什么意思?
  3. 为什么使用org.__new__(cls, *args, **kw)创建Singleton实例的属性_instance

1 个答案:

答案 0 :(得分:0)

  

cls是否等于self

不,__new__是一种静态方法(自动,不需要@staticmethod装饰器),不需要使用self。这样做很好,因为没有self可以通过它-__new__的全部要点是 create 创建self并返回它。 1

因此,它的第一个参数cls是Python希望创建的对象类型。在这里,将是Singleton

尤其是在编写此代码时:

obj = Singleton()

…Python将其转换为以下内容(略为简化):

obj = Singleton.__new__(Singleton)
if isinstance(obj, Singleton):
    obj.__init__()

  

org = super(Singleton, cls)是什么意思?

super的作用是:

  

返回将方法调用委托给类型的父级或同级类的代理对象。这对于访问已在类中重写的继承方法很有用。搜索顺序与getattr()使用的搜索顺序相同,只是类型本身被跳过。

换句话说,super(Singleton, cls)是一个与cls相似的对象(记住,它是Singleton),只是当您尝试在其上调用方法时,它会跳过方法在Singleton中定义,并且仅以方法解析顺序查找在下一个类中定义的方法-在这种情况下为object


  

为什么使用org.__new__(cls, *args, **kw)创建Singleton实例的属性_instance

请记住clsSingleton,并且org是超级代理对象,它引用与cls相同的类对象,但是具有{{1 }},而不是object的方法。 2

因此,当您调用Singleton时,它不再调用org.__new__代码并陷入无限循环,而是调用Singleton.__new__代码。但是我们将其传递为object.__new__(即cls)作为参数。因此,我们要求Singleton类型创建一个object类型的新对象。这样,结果就是一个Singleton实例,我们Singleton

但是首先,我们将其存储为return(即cls._instance),因此,下次我们尝试创建Singleton._instance时,我们可以只返回相同的Singleton


如果我们只想要一个没有任何作用的cls._instance类,那可能会更简单一些。但是Singleton可以被子类化,并且其每个子类都将是一个单例类。从此开始:

Singleton

因此,它将调用class SingleSub(Singleton): pass obj = SingleSub() 。由于SingleSub.__new__(SingleSub)不会覆盖SingleSub,因此会调用__new__,因此,在该代码中,Singleton.__new__(SingleSub)现在是cls而不是SingleSub

您应该能够从那里追踪事物,并查看Singleton最终如何以单个SingleSub结束,这与_instance(及其{{1 }}恰好在您期望的时间被调用,依此类推。


1。当然,除非您正在编写扩展模块(例如,用于CPython的C模块),否则无法创建Singleton。这就是为什么将它委派给__init__的原因-最终它会变成self或其他一些内置/扩展类型,确实知道如何创建实例。当然,您可以修改在链上传递的参数或在链上传递的super

2。在幕后,这与方法本身的工作方式非常相似,如果您已经知道方法的工作原理,这应该会使事情变得更加清楚,但是如果不知道,它可能比启蒙方法更令人困惑,因此请不要担心关于它。但是在某些时候,您应该完成Descriptor HOWTO。这很难,但是一旦您有了这个主意,Python中的所有“魔术”就会变得清晰起来。