Five Methods of Implementing Singleton Pattern in Python

  • 2021-11-10 10:02:31
  • OfStack

Basic introduction of catalogue
Advantages and disadvantages
Python Implementation
Mode 1, Metaclass Implementation: Mode 2, Inheritance Implementation: Mode 3, Decorator Implementation: Mode 4, Module Implementation: Mode 5, @ classmethod Implementation Singleton Mode:

Basic introduction

1 object can only be created once, 1 class can only create 1 object, and provide 1 global access point.

Singleton pattern should be the most widely used and simplest creation pattern.

Features: Global only 1, allowed to change

Advantages and disadvantages

Advantages:

Avoid multiple occupations of resources, such as writing files Save memory Prevent namespace from being polluted

Disadvantages:

There is no interface, no inheritance, and conflicts with the principle of single 1 responsibility. A class should only care about internal logic, but not how to instantiate it outside

Implementation of Python

Mode 1, metaclass implementation:


class MetaClass(type):
    def __call__(self, *args, **kwargs):
        """
        self : class Singleton
        """
        if not hasattr(self, "ins"):
            insObject = super(__class__, self).__call__(*args, **kwargs)
            setattr(self, "ins", insObject)
        return getattr(self, "ins")


class Singleton(object, metaclass=MetaClass):
    pass


if __name__ == "__main__":
    ins = Singleton()
    print(id(ins))
    ins = Singleton()
    print(id(ins))

Mode 2, inheritance implementation:


class ParentClass:
    def __new__(cls, *args, **kwargs) -> object:
        """
        cls : class Singeton
        """
        if not hasattr(cls, "ins"):
            insObject = super(__class__, cls).__new__(cls, *args, **kwargs)
            setattr(cls, "ins", insObject)
        return getattr(cls, "ins")


class Singleton(ParentClass):
    pass


if __name__ == "__main__":
    ins = Singleton()
    print(id(ins))
    ins = Singleton()
    print(id(ins))

Mode 3, decorator implementation:


def warpper(clsObject):
    def inner(*args, **kwargs):
        if not hasattr(clsObject, "ins"):
            insObject = clsObject(*args, **kwargs)
            setattr(clsObject, "ins", insObject)
        return getattr(clsObject, "ins")
    return inner


@warpper
class Singleton:
    pass


if __name__ == "__main__":
    ins = Singleton()
    print(id(ins))
    ins = Singleton()
    print(id(ins))

Mode 4, module implementation:


- foo.py --> ins = Singleton()
- bar.py --> from foo import ins

Mode 5, @ classmethod implements singleton mode:


class Singleton:

    @classmethod
    def getSingletonInstanceObject(cls, *args, **kwargs):
        if not hasattr(cls, "ins"):
            insObject = cls(*args, **kwargs)
            setattr(cls, "ins", insObject)
        return getattr(cls, "ins")


if __name__ == "__main__":
    ins = Singleton.getSingletonInstanceObject()
    print(id(ins))
    ins = Singleton.getSingletonInstanceObject()
    print(id(ins))


Related articles: