实现单例的三个方法

Posted gaobei

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了实现单例的三个方法相关的知识,希望对你有一定的参考价值。

# 方法一: 使用一个类方法实现单例模式
import settings

class mysql:
    __instance = None

    def __init__(self, host,port):
        self.host = host
        self.port = port

    @classmethod
    def singleton(cls):
        if not cls.__instance:     # 判断__instance 是否有值,
            cls.__instance = cls(settings.HOST, settings.PORT)   # 没有值就去settings文件中取默认的值
        return cls.__instance  # 返回值

obj1 = Mysql("1.1.1.1", 3306)
obj2 =  Mysql("1.1.1.2", 3304)
print(obj1 is obj2) # False


obj3 = Mysql.singleton()  # 第一次调用 singleton 方法 __instance 中是None
obj4 = Mysql.singleton()  # 第二次调用 singleton 方法 __instance 中是上一次调用的返回值,就是这样实现单例模式的!!!
print(obj3 is obj4)  # True




# 方法二:定制元类实现单例模式
import settings


class Mymeta(type):
    def __init__(self, name, bases, dic):   # 定义类Mysql时自动触发
        #  事先先从配置文件中取配置来造一个Mysql的实例出来
        self.__instance = object.__new__(self)  # 产生一个空对象
        self.__init__(self.__instance, settings.HOST, settings.PORT)  # 初始化对象

        super().__init__(name, bases, dic)   # 继承

    def __call__(self, *args, **kwargs):   # 实例化时自动触发
        if args or kwargs:   # 判断实例化时有没有传值
            obj = object.__new__(self)
            self.__init__(obj, *args, **kwargs)
            return obj

        return self.__instance


class Mysql(metaclass=Mymeta):
    def __init__(self, host, port):
        self.host = host
        self.port = port

obj1 = Mysql()
obj2 = Mysql()
obj3 = Mysql()
obj4 = Mysql(1.1.1.1, 3306)
print(obj1 is obj4)    # False
print(obj1 is obj2 is obj3)   # True




# 方法三: 定义一个装饰器实现单例模式
import settings


def singleton(cls):
    _instance = cls(settings.HOST, settings.PORT)

    def wrapper(*args, **kwargs):
        print(args, kwargs)
        if args or kwargs:    # or 或 , 就是args 和 kwargs 中有一个有值就是True
            obj = cls(*args, **kwargs)
            return obj
        return _instance
    return wrapper


@singleton
class Mysql:
    def __init__(self, host, port):
        self.host = host
        self.port = port


obj1 = Mysql()
obj2 = Mysql()
obj3 = Mysql()
obj4 = Mysql(1.1.1.1, 3306)
print(obj1 is obj4)   # False
print(obj1 is obj2 is obj3)    # True

 

以上是关于实现单例的三个方法的主要内容,如果未能解决你的问题,请参考以下文章

什么叫单例?

每一行代码都有灵魂,带你探究单例模式

单例模式深入探讨

实现单例的四种实现方法

static实现单例的隐患

性能比较好的单例写法