Vai al contenuto

singleton

singleton

Singleton decorator for creating singleton classes

singleton(cls)

Decorator for creating a singleton class Description: - Decorate a class with this decorator - If you happen to create another instance of the same class, it will return the previously created one - Supports creation of multiple instances of same class with different args/kwargs - Works for multiple classes - Multithreading supported Use: >>> import singleton >>> >>> @singleton ... class A: ... def init(self, args, *kwargs): ... pass >>> >>> obj1 = A(name='Mary') >>> obj2 = A(name='Mary', lname='Brown') >>> obj3 = A(name='Mary', lname='Brown') >>> obj1 is obj2 # has to be different False >>> obj2 is obj3 # has to be same True >>>

Source code in singleton.py
def singleton(cls: Callable[..., T]) -> Callable[..., T]:
    """
    Decorator for creating a singleton class
    Description:
        - Decorate a class with this decorator
        - If you happen to create another instance of the same class, it will
          return the previously created one
        - Supports creation of multiple instances of same class with different
          args/kwargs
        - Works for multiple classes
        - Multithreading supported
    Use:
        >>> import singleton
        >>>
        >>> @singleton
        ... class A:
        ...     def __init__(self, *args, **kwargs):
        ...         pass
        >>>
        >>> obj1 = A(name='Mary')
        >>> obj2 = A(name='Mary', lname='Brown')
        >>> obj3 = A(name='Mary', lname='Brown')
        >>> obj1 is obj2  # has to be different
        False
        >>> obj2 is obj3  # has to be same
        True
        >>>
    """
    previous_instances = {}
    lock = threading.RLock()

    @functools.wraps(cls)
    def wrapper(*args, **kwargs) -> T:
        """
        Wrapper function for singleton decorator
        :param args: args to be passed to the class
        :param kwargs: kwargs to be passed to the class

        :return: instance of the class
        """
        with lock:
            if cls in previous_instances:
                if previous_instances.get(cls).get('args') == (args, kwargs):
                    return previous_instances[cls].get('instance')
            previous_instances[cls] = {'args': (args, kwargs),
                                       'instance': cls(*args, **kwargs)}
            return previous_instances[cls].get('instance')

    return wrapper