可以继承python单例类吗?

时间:2011-11-23 04:34:49

标签: python inheritance singleton

我的想法是Singleton类的所有子类都应该存在任何一个对象。 我一直在尝试的代码和结果矩阵如下。在子类的情况下,矩阵似乎工作正常。我走错了路吗?它是否得到了Parent类对象和子类对象的情况?

class Singleton(object):
    _instance = None
    def __new__(cls, *args, **kwargs):
        if not cls._instance:
            cls._instance = super(Singleton, cls).__new__(
                                cls, *args, **kwargs)
        return cls._instance

class A(Singleton):
    def __new__(cls, *args, **kwargs):
        super(A, cls).__new__(cls, *args, **kwargs)

class B(Singleton):
    def __new__(cls, *args, **kwargs):
        super(B, cls).__new__(cls, *args, **kwargs)

class C(B):
    def __new__(cls, *args, **kwargs):
        super(B, cls).__new__(cls, *args, **kwargs)


if __name__ == '__main__':
    s1=Singleton()
    s2=Singleton()
    if(id(s1)==id(s2)):
        print "Same"
    else:
        print "Different"

'''
I got a result matrix for s1 and s2
           |************ s2 **************************|           
s1         |Singleton() |A()      | B()     | C()     |
===========|==========================================|
Singleton()|Same        |Different|Different|Different|
A()        |Different   |Same     |Same     |Same     |
B()        |Different   |Same     |Same     |Same     |
C()        |Different   |Same     |Same     |Same     |
'''

3 个答案:

答案 0 :(得分:3)

代码看起来很好但是为一个类及其子类选择一个单独的值是没有意义的。子类的要点在某种程度上与父类和兄弟子类不同。对我来说,每个类都没有自己独特的单例实例似乎很奇怪。

答案 1 :(得分:3)

子类“__new__()”方法都没有明确的return语句,因此它们都返回None。这就是为什么他们的新实例都是一样的。使用此代码,它们也将与Singleton()相同:

class Singleton(object):
    _instance = None
    def __new__(cls, *args, **kwargs):
        if not cls._instance:
            cls._instance = super(Singleton, cls).__new__(cls, *args, **kwargs)
        return cls._instance

class A(Singleton):
    def __new__(cls, *args, **kwargs):
        return super(A, cls).__new__(cls, *args, **kwargs)

class B(Singleton):
    def __new__(cls, *args, **kwargs):
        return super(B, cls).__new__(cls, *args, **kwargs)

class C(B):
    def __new__(cls, *args, **kwargs):
        return super(C, cls).__new__(cls, *args, **kwargs)

甚至不需要为子类定义__new__()

class A(Singleton):
    pass

class B(Singleton):
    pass

class C(B):
    pass

答案 2 :(得分:0)

我在抽象类的帮助下解决了这个问题。在我的看起来像:

from abc import ABCMeta, abstractmethod


class BasicClass(object):
    __metaclass__ = ABCMeta

    instance = None

    def __new__(cls, *args, **kwargs):
        if not cls.instance:
            cls.instance = super(BasicClass, cls).__new__(
                                    cls, *args, **kwargs)

        return cls.instance

    @abstractmethod
    def action(self):
        pass#do smthing


class FirstLevelChild(BasicClass):
    __metaclass__ = ABCMeta

    @abstractmethod
    def action(self):
        pass#do smthing in this or other abstract method
        # also pearent method can be called with help of super

class SecondLevelChild1(FirstLevelChild):
    def action(self):
        pass#do smthing unique for this class
        # in this or other abstract method
        # also pearent method can be called with help of super

class SecondLevelChild2(FirstLevelChild):
    def action(self):
        pass#do smthing unique for this class
        # in this or other abstract method
        # also pearent method can be called with help of super

让我们检查

>>> a1 = SecondLevelChild1()
>>> a2 = SecondLevelChild1()
>>> b1 = SecondLevelChild2()
>>> b2 = SecondLevelChild2()
>>> a1 == b1
False
>>> a1 ==a2
True
>>> b1 == b2
True
>>> 

注意!如果您只需要实例化最后一级子类,此解决方案将有所帮助。你无法实例化抽象类。