如何实现可子类化的单例?

时间:2012-11-29 23:31:53

标签: python

这里我是一个wxPython类的子类,并定义了一个名为singleton的类方法。

class AddressCellAttr(wx.grid.GridCellAttr):
    _instance = None

    def __init__(self):
        wx.grid.GridCellAttr.__init__(self)

        self.SetTextColour('#0000FF')

    @classmethod
    def singleton(cls):
        if cls._instance == None:
            cls._instance = cls()

        return cls._instance

class ValidAddressCellAttr(AddressCellAttr):
    def __init__(self):
        AddressCellAttr.__init__(self)

        self.SetTextColour('#00FF00')

class CorrectedAddressCellAttr(AddressCellAttr):
    def __init__(self):
        AddressCellAttr.__init__(self)

        self.SetTextColour('#FFFF00')

class InvalidAddressCellAttr(AddressCellAttr):
    def __init__(self):
        AddressCellAttr.__init__(self)

        self.SetTextColour('#FF0000')

class UnparsableAddressCellAttr(AddressCellAttr):
    def __init__(self):
        AddressCellAttr.__init__(self)

        self.SetTextColour('#555555')

其余类是第一个子类的子类。我认为单例类方法也适用于所有子类,因为它在类上运行,而子类确实是一个单独的类。

singleton上调用AddressCellAttr一次后,单例方法也会在所有子类上返回相同的对象。为什么会这样?

2 个答案:

答案 0 :(得分:0)

好吧,我在写这个问题时有点想出这个。事实证明,当调用单例方法时,它确实接收到正确的子类作为参数,但由于子类没有在任何地方专门定义_instancecls._instance将查找类链返回AddressCellAttr和原_instance

解决方案是为每个子类明确定义_instance,如下所示:

class ValidAddressCellAttr(AddressCellAttr):
    _instance = None

    def __init__(self):
        AddressCellAttr.__init__(self)

        self.SetTextColour('#00FF00')

等等。

答案 1 :(得分:0)

不确定为什么你认为你需要一个单例模式,但无论如何,你应该在__new__中真正做到这一点。

class Singleton(object):

    def __new__(cls):

        try:
            return cls._instance
        except AttributeError:
            cls._instance = object.__new__(cls)
            return cls._instance

确保所有子类都调用父__new__(),并记住__new__()__init__()的签名必须匹配。