两个课程有什么区别?他们的工作方式不同吗

时间:2018-03-22 08:51:12

标签: python python-3.x class inheritance singleton

Singleton的这两个实现有什么区别。在父类中创建变量_instance是否使其与第二个类的工作方式不同?

class SingletonA(object):
    _instance = None

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


class SingletonB(object):
    def __new__(cls, *args, **kwargs):
        if not hasattr(cls, "_instance"):
            cls._instance = object.__new__(cls, *args, **kwargs)
        return cls._instance


# sample usage
class A(SingletonA):
    pass


print(A() == A()) #True

2 个答案:

答案 0 :(得分:6)

对于发布的代码,没有区别。

但是,如果您的子类实现__bool____len__,则第一个示例将失败,因为即使已设置实例,not self._instance也可能返回True。你真的想用if self._instance is None:代替:

>>> class AlwaysFalse(object):
...     def __bool__(self): return False
...
>>> if not AlwaysFalse():
...     print("It doesn't exist? Should we create a new one?")
...
It doesn't exist? Should we create a new one?
>>> AlwaysFalse() is None
False

除此之外,差异很大。

您还希望使用身份测试来检查单例实现是否正常工作;一个子类可以实现__eq__ method并返回True,即使这两个对象是不同的(所以不是单例):

>>> class EqualNotSingleton(object):
...     def __eq__(self, other): return True
...
>>> EqualNotSingleton() == EqualNotSingleton()
True
>>> EqualNotSingleton() is EqualNotSingleton()
False

答案 1 :(得分:1)

同意@Martijin Pieters回答,

此外,提供另一种方法来实现名为Borg的Singleton,它们共享相同的状态:

class Borg:
    _shared_state = {}
    def __new__(cls, *args, **kwargs):
        obj = super(Borg, cls).__new__(cls, *args, **kwargs)
        obj.__dict__ = cls._shared_state
        return obj

class S1(Borg):
    pass

class S2(Borg):
    pass

assert S1() is not S1()
S1().v = 1
assert S1().v == S1().v
assert S1().v == S2().v


class S3(Borg):
    # if want to have a different state
    _shared_state = {}
    pass

S3().v = 2
assert S3().v != S1().v