极速网站建设哪家便宜,网站需求方案,北京搜索引擎优化,wordpress导出html代码单例模式单例模式(Singleton Pattern)是一种常用的软件设计模式#xff0c;该模式的主要目的是确保某一个类只有一个实例存在。当你希望在整个系统中#xff0c;某个类只能出现一个实例时#xff0c;单例对象就能派上用场。比如#xff0c;某个服务器程序的配置信息存放在一…单例模式单例模式(Singleton Pattern)是一种常用的软件设计模式该模式的主要目的是确保某一个类只有一个实例存在。当你希望在整个系统中某个类只能出现一个实例时单例对象就能派上用场。比如某个服务器程序的配置信息存放在一个文件中客户端通过一个 AppConfig 的类来读取配置文件的信息。如果在程序运行期间有很多地方都需要使用配置文件的内容也就是说很多地方都需要创建 AppConfig 对象的实例这就导致系统中存在多个 AppConfig 的实例对象而这样会严重浪费内存资源尤其是在配置文件内容很多的情况下。事实上类似 AppConfig 这样的类我们希望在程序运行期间只存在一个实例对象。在 Python 中我们可以用多种方法来实现单例模式实现单例模式的几种方式1.使用模块其实Python 的模块就是天然的单例模式因为模块在第一次导入时会生成 .pyc 文件当第二次导入时就会直接加载 .pyc 文件而不会再次执行模块代码。因此我们只需把相关的函数和数据定义在一个模块中就可以获得一个单例对象了。如果我们真的想要一个单例类可以考虑这样做mysingleton.pyclass Singleton(object):def foo(self):passsingleton Singleton()将上面的代码保存在文件 mysingleton.py 中要使用时直接在其他文件中导入此文件中的对象这个对象即是单例模式的对象from a import singleton2.使用类class Singleton(object):def __init__(self):passclassmethoddef instance(cls, *args, **kwargs):if not hasattr(Singleton, _instance):Singleton._instance Singleton(*args, **kwargs)return Singleton._instance一般情况大家以为这样就完成了单例模式但是这样当使用多线程时会存在问题class Singleton(object):def __init__(self):passclassmethoddef instance(cls, *args, **kwargs):if not hasattr(Singleton, _instance):Singleton._instance Singleton(*args, **kwargs)return Singleton._instanceimport threadingdef task(arg):obj Singleton.instance()print(obj)for i in range(10):t threading.Thread(targettask,args[i,])t.start()程序执行后打印结果如下看起来也没有问题那是因为执行速度过快如果在init方法中有一些IO操作就会发现问题了下面我们通过time.sleep模拟我们在上面__init__方法中加入以下代码def __init__(self): import time time.sleep(1)重新执行程序后结果如下问题出现了按照以上方式创建的单例无法支持多线程解决办法加锁未加锁部分并发执行,加锁部分串行执行,速度降低,但是保证了数据安全import timeimport threadingclass Singleton(object):_instance_lock threading.Lock()def __init__(self):time.sleep(1)classmethoddef instance(cls, *args, **kwargs):with Singleton._instance_lock:if not hasattr(Singleton, _instance):Singleton._instance Singleton(*args, **kwargs)return Singleton._instancedef task(arg):obj Singleton.instance()print(obj)for i in range(10):t threading.Thread(targettask,args[i,])t.start()time.sleep(20)obj Singleton.instance()print(obj)打印结果如下这样就差不多了但是还是有一点小问题就是当程序执行时执行了time.sleep(20)后下面实例化对象时此时已经是单例模式了但我们还是加了锁这样不太好再进行一些优化把intance方法改成下面的这样就行classmethoddef instance(cls, *args, **kwargs):if not hasattr(Singleton, _instance):with Singleton._instance_lock:if not hasattr(Singleton, _instance):Singleton._instance Singleton(*args, **kwargs)return Singleton._instance这样一个可以支持多线程的单例模式就完成了import timeimport threadingclass Singleton(object):_instance_lock threading.Lock()def __init__(self):time.sleep(1)classmethoddef instance(cls, *args, **kwargs):if not hasattr(Singleton, _instance):with Singleton._instance_lock:if not hasattr(Singleton, _instance):Singleton._instance Singleton(*args, **kwargs)return Singleton._instancedef task(arg):obj Singleton.instance()print(obj)for i in range(10):t threading.Thread(targettask,args[i,])t.start()time.sleep(20)obj Singleton.instance()print(obj)这种方式实现的单例模式使用时会有限制以后实例化必须通过 obj Singleton.instance()如果用 objSingleton() ,这种方式得到的不是单例3.基于__new__方法实现(推荐使用方便)通过上面例子我们可以知道当我们实现单例时为了保证线程安全需要在内部加入锁我们知道当我们实例化一个对象时是先执行了类的__new__方法(我们没写时默认调用object.__new__)实例化对象然后再执行类的__init__方法对这个对象进行初始化所有我们可以基于这个实现单例模式import threadingclass Singleton(object):_instance_lock threading.Lock()def __init__(self):passdef __new__(cls, *args, **kwargs):if not hasattr(Singleton, _instance):with Singleton._instance_lock:if not hasattr(Singleton, _instance):Singleton._instance object.__new__(cls, *args, **kwargs)return Singleton._instanceobj1 Singleton()obj2 Singleton()print(obj1,obj2)def task(arg):obj Singleton()print(obj)for i in range(10):t threading.Thread(targettask,args[i,])t.start()打印结果如下采用这种方式的单例模式以后实例化对象时和平时实例化对象的方法一样 obj Singleton()4.基于metaclass方式实现相关知识1.类由type创建创建类时候type的__init__方法自动执行类() 执行type的 __call__方法(类的__new__方法,类的__init__方法)2.对象由类创建创建对象时候类的__init__方法自动执行对象()执行类的 __call__ 方法例子class Foo:def __init__(self):passdef __call__(self, *args, **kwargs):passobj Foo()# 执行type的 __call__ 方法调用 Foo类(是type的对象)的 __new__方法用于创建对象然后调用 Foo类(是type的对象)的 __init__方法用于对对象初始化。obj() # 执行Foo的 __call__ 方法元类的使用class SingletonType(type):def __init__(self,*args,**kwargs):super(SingletonType,self).__init__(*args,**kwargs)def __call__(cls, *args, **kwargs): # 这里的cls即Foo类print(cls,cls)obj cls.__new__(cls,*args, **kwargs)cls.__init__(obj,*args, **kwargs) # Foo.__init__(obj)return objclass Foo(metaclassSingletonType): # 指定创建Foo的type为SingletonTypedef __init__(self):passdef __new__(cls, *args, **kwargs):return object.__new__(cls, *args, **kwargs)obj Foo()实现单例模式import threadingclass SingletonType(type):_instance_lock threading.Lock()def __call__(cls, *args, **kwargs):if not hasattr(cls, _instance):with SingletonType._instance_lock:if not hasattr(cls, _instance):cls._instance super(SingletonType,cls).__call__(*args, **kwargs)return cls._instanceclass Foo(metaclassSingletonType):def __init__(self,name):self.name nameobj1 Foo(name)obj2 Foo(name)print(obj1,obj2)以上这篇基于Python中单例模式的几种实现方式及优化详解就是小编分享给大家的全部内容了希望能给大家一个参考也希望大家多多支持我们。本文标题: 基于Python中单例模式的几种实现方式及优化详解本文地址: http://www.cppcns.com/jiaoben/python/217200.html