Python Singleton

2019-03-10  本文已影响0人  我的昵称是小狼

如何实现Python中的单例

1.重写Class的new方法

#__new__函数就是class在创建对象时会调用的方法
#通过重写__new__函数可以控制只创建一个对象
#子类可以通过重写__new__函数
class Singleton(object):
    _instance = None
    def __new__(class_, *args, **kwargs):
        if not isinstance(class_._instance, class_):
            class_._instance = object.__new__(class_, *args, **kwargs)
        return class_._instance

2.指定metaclass

#通过metaclass控制class的__new__函数
#子类除非指定别的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)
        else:
           #这段代码的作用是每次都调用class的init函数
            cls._instances[cls].__init__(*args, **kwargs)
        return cls._instances[cls]

#Python2
class MyClass(BaseClass):
    __metaclass__ = Singleton

#Python3
class MyClass(BaseClass, metaclass=Singleton):
    pass

PS:上面的写法都没有加线程锁,如果考虑在多线程的环境下使用需要加线程锁

import functools
import threading

lock = threading.Lock()


def synchronized(lock):
    """ Synchronization decorator """
    def wrapper(f):
        @functools.wraps(f)
        def inner_wrapper(*args, **kw):
            with lock:
                return f(*args, **kw)
        return inner_wrapper
    return wrapper


class Singleton(type):
    _instances = {}

    @synchronized(lock)
    def __call__(cls, *args, **kwargs):
        if cls not in cls._instances:
            cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs)
        return cls._instances[cls]


class SingletonClass(metaclass=Singleton):
    pass

PS: 在Python中,import默认只会导入一次,除非使用reload函数刷新,否则每个module只会导入一次,这样的话,如果导入一个变量,则这个变量就相当于单例

上一篇下一篇

猜你喜欢

热点阅读