代码之家  ›  专栏  ›  技术社区  ›  hal

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

  •  1
  • hal  · 技术社区  · 7 年前

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

    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 回复  |  直到 7 年前
        1
  •  6
  •   Martijn Pieters    7 年前

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

    如果您的子类实现 __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 和返回 真的 即使这两个对象是不同的(因此不是单一对象):

    >>> class EqualNotSingleton(object):
    ...     def __eq__(self, other): return True
    ...
    >>> EqualNotSingleton() == EqualNotSingleton()
    True
    >>> EqualNotSingleton() is EqualNotSingleton()
    False
    
        2
  •  1
  •   Menglong Li    7 年前

    同意@Martijin Pieters的回答,

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

    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