日照信息网:浅谈单利模式及其应用场景(Python)

admin/2020-02-24/ 分类:科技/阅读:
C#中HashSet的重复性与判等运算重载

python 中的单利模式

使用场景:
Python的logger就是一个单例模式,用以日志记录
Windows的资源管理器是一个单例模式
线程池,数据库连接池等资源池一般也用单例模式
网站计数器

从这些使用场景我们可以总结下什么情况下需要单例模式:

 1. 当每个实例都会占用资源,而且实例初始化会影响性能,这个时候就可以考虑使用单例模式,它给我们带来的好处是只有一个实例占用资源,并且只需初始化一次; 2. 当有同步需要的时候,可以通过一个实例来进行同步控制,比如对某个共享文件(如日志文件)的控制,对计数器的同步控制等,这种情况下由于只有一个实例,所以不用担心同步问题
  1. __new__方法实现
 class Singleton(object): __instance = None def __new__(cls, *args, **kwargs): if cls.__instance is None: cls.__instance = super(Singleton, cls).__new__(cls, *args, **kwargs) # 可以在这里给实力对象绑定一些固有属性 # cls.__instance.appkey = "" return cls.__instance
  • 1.1
 class Singleton(object): def __new__(cls, *args, **kwargs): # 判断是否存在类属性_instance,_instance是类CCP的唯一对象,即单例 if not hasattr(Singleton, "__instance"): cls.__instance = super(Singleton, cls).__new__(cls, *args, **kwargs) # cls.__instance = object.__new__(cls) return cls.__instance

但是以上的方法在多线程中会有线程安全问题,当有多个线程同时去初始化对象时,就很可能同时判断__instance is None,从而进入初始化instance的代码中(如果有__init__方法)。所以需要用互斥锁来解决这个问题。

SpringCloud微服务:阿里开源组件Nacos,服务和配置管理

  1. 实现线程安全的单例模式
 import threading try: from synchronize import make_synchronized except ImportError: def make_synchronized(func): import threading func.__lock__ = threading.Lock() # 用装饰器实现同步锁 def synced_func(*args, **kwargs): with func.__lock__: return func(*args, **kwargs) return synced_func class Singleton(object): __instance = None @make_synchronized def __new__(cls, *args, **kwargs): if not cls.__instance: cls.__instance = object.__new__(cls) return cls.__instance def __init__(self): self.blog = "blog" # ------------- def worker(): e = Singleton() print(id(e)) def meta(): e1 = Singleton() e2 = Singleton() e1.blog = 123 print(e1.blog) print(e2.blog) print(id(e1)) print(id(e2)) if __name__ == "__main__": meta() tasks = [threading.Thread(target=worker) for _ in range(20)] for task in tasks: task.start() task.join()
  1. 使用装饰器来获取单例对象
 # 装饰器(decorator)可以动态地修改一个类或函数的功能 import functools def singleton(cls): __instance = {} @functools.wraps(cls) def getinstance(*args, **kwargs): if cls not in __instance: __instance[cls] = cls(*args, **kwargs) return __instance[cls] return getinstance @singleton class MyClass(object): a = 1 

我们定义了一个装饰器 singleton,它返回了一个内部函数 getinstance,该函数会判断某个类是否在字典 instances 中,如果不存在,则会将 cls 作为 key,cls(*args, **kw) 作为 value 存到 instances 中,否则,直接返回 instances[cls]。

  1. 使用metaclass元类创建单例
    元类(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): def __init__(self): self.blog = "blog"

参考:
Python 中的单例模式
设计模式(Python)-单例模式

,

Sunbet

Sunbet www.169894.com Sunbet是进入Sunbet的主力站点。Sunbet开放Sunbet会员开户网址(www.sunbet.us)、Sunbet代理开户(www.sunbet.us)、Sunbet手机版下载(www.sunbet.us)、Sunbet电脑客户端下载(www.sunbet.us)等业务。

TAG:
阅读:
广告 330*360
广告 330*360
Sunbet_进入申博sunbet官网
微信二维码扫一扫
关注微信公众号
新闻自媒体 Copyright © 2002-2019 Sunbet 版权所有
二维码
意见反馈 二维码