arkilis
5/19/2017 - 12:40 AM

Singleton in Python

Singleton in Python

# Approach 1: Use Module
# A python module is Singleton by nature, as when it is imported, a `.pyc` file will be created. So in the next time when moudle was imported again, .pyc will be imported directly and module source code will not be running again.

# mysingleton_module.py
class My_Singleton(object):
    def foo(self):
        pass
 
my_singleton = My_Singleton()

# in where you want to use

from mysingleton import my_singleton
my_singleton.foo()

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

# Approach 2: Use __new__

class Singleton(object):
    def __new__(cls, *args, **kwargs): # override the __new__ method
        if not hasattr(cls, '_instance'):
            cls._instance = super(Singleton, cls).__new__(cls, *args, **kwargs)
        return cls._instance
 
class Foo(Singleton):
    a = 1

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

# Approach 3: Use __metaclass__

class Singleton(type):
    _instances = {}
    def __call__(cls, *args, **kwargs):
        if cls not in cls._instances:
            cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs)
        return cls._instances[cls]
 
# Python2
class MyClass(object):
    __metaclass__ = Singleton
 
# Python3
# class MyClass(metaclass=Singleton):
#    pass
    
################################################################

# Approach 4: Use decorator


from functools import wraps
 
def singleton(cls):
    instances = {}
    @wraps(cls)
    def getinstance(*args, **kw):
        if cls not in instances:
            instances[cls] = cls(*args, **kw)
        return instances[cls]
    return getinstance
 
@singleton
class MyClass(object):
    a = 1