#!# ============
#!#  Singletons
#!# ============
#!#
#!# This page contains several singleton implementations.

####################################################################################################

#!# This implementation, based on metaclass, supports subclassing and is thread safe. Best
#!# implementation if we need subclassing.

class SingletonMetaclass(type):

    """A singleton metaclass.

    This implementation supports subclassing and is thread safe.

    """

    ##############################################

    def __init__(cls, class_name, base_classes, namespace):

        # Called just after cls creation in order to complete cls

        type.__init__(cls, class_name, base_classes, namespace)

        cls._instance = None

        # A factory function that returns a new reentrant lock object.
        import threading # SHOULD BE PLACED AT TOP OF THE FILE
        cls._rlock = threading.RLock()

    ##############################################

    def __call__(cls, *args, **kwargs):

        # Called when cls is instantiated: cls(...)
        # type.__call__ dispatches to the cls.__new__ and cls.__init__ methods

        with cls._rlock:
            if cls._instance is None:
                cls._instance = type.__call__(cls, *args, **kwargs)

        return cls._instance

####################################################################################################

#!# This implementation, based on decorator and a class wrapper, doesn't support subclassing.  With
#!# a decorator, each class and its subclasses must be decorated in order to be a singleton.

class singleton:

    """A singleton class decorator.

    This implementation doesn't support subclassing.

    """

    ##############################################

    def __init__(self, cls):

        self._cls = cls
        self._instance = None

    ##############################################

    def __call__(self, *args, **kwargs):

        if self._instance is None:
            self._instance = self._cls(*args, **kwargs)

        return self._instance

####################################################################################################

#!# Another implementation based on decorator but using a closure to wrap the class:

def singleton(cls):

    """A singleton function decorator.

    This implementation doesn't support subclassing.

    """

    instances = {}

    # Return a closure
    def get_instance(*args, **kwargs):
        if cls not in instances:
            instances[cls] = cls(*args, **kwargs)
        return instances[cls]

    return get_instance

3.4.1. Singletons

This page contains several singleton implementations. This implementation, based on metaclass, supports subclassing and is thread safe. Best implementation if we need subclassing.

class SingletonMetaclass(type):

    """A singleton metaclass.

    This implementation supports subclassing and is thread safe.

    """

    def __init__(cls, class_name, base_classes, namespace):

        # Called just after cls creation in order to complete cls

        type.__init__(cls, class_name, base_classes, namespace)

        cls._instance = None

        # A factory function that returns a new reentrant lock object.
        import threading # SHOULD BE PLACED AT TOP OF THE FILE
        cls._rlock = threading.RLock()

    def __call__(cls, *args, **kwargs):

        # Called when cls is instantiated: cls(...)
        # type.__call__ dispatches to the cls.__new__ and cls.__init__ methods

        with cls._rlock:
            if cls._instance is None:
                cls._instance = type.__call__(cls, *args, **kwargs)

        return cls._instance

This implementation, based on decorator and a class wrapper, doesn’t support subclassing. With a decorator, each class and its subclasses must be decorated in order to be a singleton.

class singleton:

    """A singleton class decorator.

    This implementation doesn't support subclassing.

    """

    def __init__(self, cls):

        self._cls = cls
        self._instance = None

    def __call__(self, *args, **kwargs):

        if self._instance is None:
            self._instance = self._cls(*args, **kwargs)

        return self._instance

Another implementation based on decorator but using a closure to wrap the class:

def singleton(cls):

    """A singleton function decorator.

    This implementation doesn't support subclassing.

    """

    instances = {}

    # Return a closure
    def get_instance(*args, **kwargs):
        if cls not in instances:
            instances[cls] = cls(*args, **kwargs)
        return instances[cls]

    return get_instance