浅谈单利模式及其应用场景(Python)
python 中的单利模式
使用场景:
+ Python的logger就是一个单例模式,用以日志记录
+ Windows的资源管理器是一个单例模式
+ 线程池,数据库连接池等资源池一般也用单例模式
+ 网站计数器
从这些使用场景我们可以总结下什么情况下需要单例模式:
1. 当每个实例都会占用资源,而且实例初始化会影响性能,这个时候就可以考虑使用单例模式,它给我们带来的好处是只有一个实例占用资源,并且只需初始化一次;
2. 当有同步需要的时候,可以通过一个实例来进行同步控制,比如对某个共享文件(如日志文件)的控制,对计数器的同步控制等,这种情况下由于只有一个实例,所以不用担心同步问题。
- __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__方法)。所以需要用互斥锁来解决这个问题。
- 实现线程安全的单例模式
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()
- 使用装饰器来获取单例对象
# 装饰器(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]。
- 使用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)-单例模式
浅谈单利模式及其应用场景(Python)的更多相关文章
- 浅谈MVVM模式和MVP模式——Vue.js向
浅谈MVVM模式和MVP模式--Vue.js向 传统前端开发的MVP模式 MVP开发模式的理解过程 首先代码分为三层: model层(数据层), presenter层(控制层/业务逻辑相关) view ...
- 设计模式浅谈----策略模式(c#及java实现)
一.何为策略模式 策略模式是行为型模式的一种,主要用于需要使用不同的算法来处理不同的数据对象时使用,是一种可以在运行时选择算法的设计模式.也称为政策模式. 主要解决:在有多种算法相似的情况下,使用 i ...
- 浅谈ThreadLocal模式
一.前言: ThreadLocal模式,严格意义上不是一种设计模式,而是java中解决多线程数据共享问题的一个方案.ThreadLocal类是java JDK中提供的一个类,用来解决线程安全问题,并不 ...
- 浅谈代理模式与java中的动态代理
代理模式的定义: 代理模式是一个使用律非常高的模式,定义如下: 为其他对象提供一种代理,以控制对这个对象的访问. 类图: 简单的静态代理: public interface IRunner{ //这是 ...
- iOS:个人浅谈工厂模式
一.什么是工厂方法? 正式的解释是:在基类中定义创建对象的一个接口,让子类决定实例化哪个类.工厂方法让一个类的实例化延迟到子类中进行.工厂方法要解决的问题是对象的创建时机,它提供了一种扩展的策略,很好 ...
- 浅谈pageobject模式
先来看两段代码 代码1: package com.zlshuo.selenium.nonaming.pageobject; /** * @author leshuo * @version 2014年5 ...
- 浅谈MVC模式
MVC模式(三层架构模式) (Model-View-Controller)是软件工程中的一种软件架构模式,把软件系统分为三个基本部分:模型(Model).视图(View)和控制器(Controller ...
- 浅谈MVC模式与MVVM模式的区别
MVC模式: M:Model(数据模型),用于存放数据 V:View(视图),也就是用户界面 C:Controller是Model和View的协调者,Controller把Model中的数据拿过来给V ...
- Swift语言精要 - 浅谈代理模式(Delegate)
在iOS编程中,我们经常谈到代理代理,也就是delegate,那么什么是代理呢? 我们来看一下cocoa对它的描述: Delegation is Cocoa’s term for passing of ...
随机推荐
- ReactNative: 将自定义的ReactNative组件制作成第三方库的详细流程(制作-->发布)
一.简介 在讲本篇博文之前,需要你熟知怎么自定义ReactNative组件,然后才好学习将自定义的ReactNative组件制作成第三方库.本文中的自定义的ReactNative组件LoginMana ...
- Xmind: ZEN快捷键
- 你在使用什么 Redis 客户端工具?
今天发现一个不错的 Redis 客户端工具:AnotherRedisDesktopManager. 兼容 Windows Mac Linux,号称又快又稳定,加载大量 keys 时也不会崩溃. Git ...
- [bzoj2038] [洛谷P1494] [2009国家集训队] 小Z的袜子(hose)
Description 作为一个生活散漫的人,小Z每天早上都要耗费很久从一堆五颜六色的袜子中找出一双来穿.终于有一天,小Z再也无法忍受这恼人的找袜子过程,于是他决定听天由命-- 具体来说,小Z把这N只 ...
- ZJCTF预赛一个.py的逆向题
#!/usr/bin/env python # -*- coding:utf-8 -*- from hashlib import sha256 def xor(a,b): result = [] fo ...
- Python脚本通过ftp协议移植文件
需求 项目需要定时移植多个客户服务器的文件到公司服务器上,确保文件定时同步和生成监控日志 机制原理 1.客户和公司服务器同时安装vpn,绕过复杂的网关,linux下使用的OpenVPN 2.服务器定时 ...
- mysql输出到页面MVC模式
上一篇文章我提到过在jsp页面不好 这篇文章讲的就是界面和代码分离,可以初步实现两个或三个人合作完成一个项目 好,废话不多说,进正题 这次又四个步骤 第一步,新建项目,新建实体类 第二步,新建数据库, ...
- 如何用Git.io来生成自定义后缀名的短网址
如何用Git.io来生成自定义后缀名的短网址 git.io是Github的官方短网址,它是用来缩短Github上项目的网址. 效果:Git.io/wacsh将会跳转到https://xhemj.git ...
- SpringBoot缓存篇Ⅱ --- 整合Redis以及序列化机制
一.Redis环境搭建 系统默认是使用ConcurrentMapCacheManager,然后获取和创建ConcurrentMapCache类型的缓存组件,再将数据保存在ConcurrentMap中 ...
- DirectX11 With Windows SDK--29 计算着色器:内存模型、线程同步;实现顺序无关透明度(OIT)
前言 由于透明混合在不同的绘制顺序下结果会不同,这就要求绘制前要对物体进行排序,然后再从后往前渲染.但即便是仅渲染一个物体(如上一章的水波),也会出现透明绘制顺序不对的情况,普通的绘制是无法避免的.如 ...