python–单例模式

前言

单例模式是最常使用的一种设计模式,该模式的目的是确保在一个系统中,一个类只有一个实例

1.单例模式应用场景

数据库链接、Socket(套接字)创建链接

2.实现的5种方法

1.使用模块

其实也就是平时所说的调用第三方库,比如beautifulsoup、pymongo…
代码如下(自编写类):

class Singleton():
    def __init__(self, name):
        self.name = name

    def do_something(self):
        pass

singleton = Singleton('模块单例')

在其他脚本里,将自己写的类看作库调用

from my_singleton import singleton

在任何引用singleton的脚本里,singleton都是同一个对象,这就确保了系统中只有一个Singleton的实例。

2.使用装饰器

如果对于装饰器还不太了解的话,可以自行查阅下
代码如下(示例):

def Singleton(cls):
    instance = {}

    def _singleton_wrapper(*args, **kargs):
        if cls not in instance:
            instance[cls] = cls(*args, **kargs)
        return instance[cls]

    return _singleton_wrapper


@Singleton
class SingletonTest(object):
    def __init__(self, name):
        self.name = name


slt_1 = SingletonTest('第1次创建')
print(slt_1.name)
slt_2 = SingletonTest('第2次创建')
print(slt_1.name, slt_2.name)

print(slt_1 is slt_2)

输出结果

第1次创建
第1次创建 第1次创建
True

创建slt_2 对象时,instance 字典中已经存在SingletonTest 这个key,因此直接返回了第一次创建的对象,slt_1 和 slt_2 是同一个对象。

3.使用类

class Singleton(object):

    def __init__(self, name):
        self.name = name

    @classmethod
    def instance(cls, *args, **kwargs):
        if not hasattr(Singleton, "_instance"):
            Singleton._instance = Singleton(*args, **kwargs)
        return Singleton._instance

single_1 = Singleton.instance('第1次创建')
single_2 = Singleton.instance('第2次创建')

print(single_1 is single_2)     # True

4.基于__new__方法实现

__new__方法是构造函数,是真正的用来创建对象的

from threading import RLock

class Singleton(object):
    single_lock = RLock()#上锁

    def __init__(self, name):
        self.name = name

    def __new__(cls, *args, **kwargs):
        with Singleton.single_lock:
            if not hasattr(Singleton, "_instance"):
                Singleton._instance = object.__new__(cls)

        return Singleton._instance

single_1 = Singleton('第1次创建')
single_2 = Singleton('第2次创建')

print(single_1.name, single_2.name)   # 第2次

5.使用元类

from threading import RLock

class SingletonType(type):
    single_lock = RLock()

    def __call__(cls, *args, **kwargs):   # 创建cls的对象时候调用
        with SingletonType.single_lock:
            if not hasattr(cls, "_instance"):
                cls._instance = super(SingletonType, cls).__call__(*args, **kwargs)     # 创建cls的对象

        return cls._instance


class Singleton(metaclass=SingletonType):
    def __init__(self, name):
        self.name = name


single_1 = Singleton('第1次创建')
single_2 = Singleton('第2次创建')

print(single_1.name, single_2.name)     # 第1次创建 第1次创建
print(single_1 is single_2)     # True

class Singleton(metaclass=SingletonType) 这行代码定义了一个类,这个类是元类SingletonType 的实例,是元类SingletonType的__new__构造出来的,Singleton是实例,那么Singleton(‘第1次创建’)就是在调用元类SingletonType 的__call__方法,__call__方法可以让类的实例像函数一样去调用

3.类的绑定方法单例模式例子

class mysql_connection:#数据库连接
    __instance = None#初始定义为空
    def __init__(self,ip,port,username,password):#初始化参数
        self.ip = ip
        self.port = port
        self.username = username
        self.password = password
    @classmethod
    def func(cls):
        if cls.__instance is None:#没有则创建
            cls.__instance = cls('127.0.0.1',3306,'root','root')
        return cls.__instance
con1 = mysql_connection.func()

4.参考文章

Python 单例模式 详解
python实现单例模式的5种方法

文章出处登录后可见!

已经登录?立即刷新

共计人评分,平均

到目前为止还没有投票!成为第一位评论此文章。

(0)
心中带点小风骚的头像心中带点小风骚普通用户
上一篇 2023年3月10日
下一篇 2023年3月10日

相关推荐