聊一聊python的单例模式
单例模式
单例模式(Singleton Pattern)是一种常用的软件设计模式,该模式的主要目的是确保某一个类只有一个实例存在。当你希望在整个系统中,某个类只能出现一个实例时,单例对象就能派上用场。
四种方法:
- 使用模块
- 使用
__new__ - 使用装饰器(decorator)
- 使用元类(metaclass)
- 使用类方法
1. 使用__new__()
import threading Lock = threading.Lock() # 加锁为了保证线程安全 class Foo(object):
__isinstance = None def __new__(cls, *args, **kwargs):
# 如果发现__isinstance 有值了直接返回,不进锁了
if not cls.__isinstance:
with Lock:
if not cls.__isinstance:
cls.__isinstance = super(Foo,cls).__new__(cls)
return cls.__isinstance obj = Foo()
obj2 = Foo() print(obj,obj2)
2. 模块导入
其实,Python 的模块就是天然的单例模式,因为模块在第一次导入时,会生成 .pyc 文件,当第二次导入时,就会直接加载 .pyc 文件,而不会再次执行模块代码。因此,我们只需把相关的函数和数据定义在一个模块中,就可以获得一个单例对象了。如果我们真的想要一个单例类,可以考虑这样做:
# mysingleton.py
class My_Singleton(object):
def foo(self):
pass my_singleton = My_Singleton()
将上面的代码保存在文件 mysingleton.py 中,然后这样使用:
from mysingleton import my_singleton my_singleton.foo()
3. 使用装饰器
基本思想为:
1、在装饰器中添加一个字典类型的自由变量_instance;
2、在闭包中判断类名是否存在于_instance中,如果不存在则创建一个类的事例,并讲其添加到字典中;如果存在则不进行实例化,直接返回字典中的实例;
def Singleton(cls):
_instance = {}
def _singleton(*args, **kargs):
if cls not in _instance:
_instance[cls] = cls(*args, **kargs)
return _instance[cls]
return _singleton @Singleton
class A(object):
a = 1
def __init__(self, x = 0):
self.x = x a1 = A(2)
a2 = A(3)
print id(a1)
print id(a2)
print a1.x
print a2.x '''''
----------------------------------------
45838576
45838576
2
2
'''
4. 使用元类
示例化一个类的时候,如果他有元类,先执行元类的__call__方法,cll方法的第一个参数就是子类,先执行子类的__new__,子类没有执行objects的__new__,实例化后执行初始化__init__ ,修改isinstance的值并返回
import threading
Lock = threading.Lock()
class Singleton(type):
def __call__(cls, *args, **kwargs):
if not hasattr(cls,"isinstance"):
with Lock:
if not hasattr(cls,"isinstance"):
obj = cls.__new__(cls,*args,**kwargs)
obj.__init__(*args,**kwargs)
setattr(cls,"isinstance",obj)
return getattr(cls,"isinstance")
return getattr(cls,"isinstance")
class Foo(object,metaclass=Singleton):
def __init__(self):
self.name = "zhou"
obj = Foo()
obj2 = Foo()
print(obj,obj2)
5. 使用类方法的单例模式
加锁为类线程安全
import threading
import time class Foo(object):
instance = None
lock = threading.Lock() def __init__(self):
self.a1 = 1
self.a2 = 2
import time
import random
time.sleep(2) @classmethod
def get_instance(cls,*args,**kwargs):
if not cls.instance:
with cls.lock:
if not cls.instance:
obj = cls(*args,**kwargs)
cls.instance = obj
return cls.instance
return cls.instance
def task():
obj = Foo.get_instance()
print(obj) import threading
for i in range(5):
t = threading.Thread(target=task,)
t.start() time.sleep(10)
# 实例化时调用get_instance
Foo.get_instance()
聊一聊python的单例模式的更多相关文章
- python实现单例模式的三种方式及相关知识解释
python实现单例模式的三种方式及相关知识解释 模块模式 装饰器模式 父类重写new继承 单例模式作为最常用的设计模式,在面试中很可能遇到要求手写.从最近的学习python的经验而言,singlet ...
- Python 基于python实现单例模式
基于python实现单例模式 by:授客 QQ:1033553122 概念 简单说,单例模式(也叫单件模式)的作用就是保证在整个应用程序的生命周期中,任何一个时刻,单例类的实例都只存在一个(当然也 ...
- python 以单例模式封装logging相关api实现日志打印类
python 以单例模式封装logging相关api实现日志打印类 by:授客QQ:1033553122 测试环境: Python版本:Python 2.7 实现功能: 支持自由配置,如下lo ...
- python的单例模式:
python的单例模式:http://funhacks.net/2017/01/17/singleton/ https://www.cnblogs.com/huchong/p/8244279.html ...
- 【Python】单例模式Singleton
前两天一个面试被问到python中单例模式有几种实现方式,只答出了可以用元类实现...然后就想不起来了. 之后翻书,原来这些之前都见过的啊.... 1.手动实现真正创建实例的方法__new__()来实 ...
- 浅谈Python设计模式 - 单例模式
本篇主要介绍一下关于Python的单例模式,即让一个类对象有且只有一个实例化对象. 一.使用__new__方法(基类) 要实现单例模式,即为了让一个类只能实例化一个实例,那么我们可以去想:既然限制创建 ...
- 【python】Python的单例模式
原文:http://blog.csdn.net/ghostfromheaven/article/details/7671853 单例模式:保证一个类仅有一个实例,并提供一个访问他的全局访问点. 实现某 ...
- python实现单例模式
有这么一种场景,我们把数据封装到类体或类的某个方法里,然而我们new出这个类只是为了拿到这部分数据,那么当多次这样调用的时候,每次都来拿数据并放到内存中大大浪费了内存. 那我们就可以想,我们拿到一次数 ...
- Python 实现单例模式的一些思考
一.问题:Python中如何实现单例模式 单例模式指一个类只能实例化一个对象. 二.解决方案: 所有资料参考于: http://python.jobbole.com/87294/ https://ww ...
随机推荐
- 第二百七十节,Tornado框架-生成验证码图片,以及验证码结合Session验证
Tornado框架-生成验证码图片,以及验证码结合Session验证 第一.生成验证码图片 生成验证码图片需要两个必须模块 1.python自带的random(随机模块) 2.Pillow()图像处 ...
- 说说JSON和JSONP 也许你会豁然开朗
说到AJAX就会不可避免的面临两个问题,第一个是AJAX以何种格式来交换数据?第二个是跨域的需求如何解决 前言 由于Sencha Touch 2这种开发模式的特性,基本决定了它原生的数据交互行为几乎只 ...
- 学习《深入理解C#》—— 数据类型、排序和过滤 (第一章1.1---1.2)
引言 在开始看这本书之前看过一些技术博客,填补自己对于一些知识点的不足.无意中发现了<深入理解C#>这本书,本书主要探讨C# 2.C# 3和C# 4的细节与特性,所以做了一下阅读笔记,欢迎 ...
- Laravel5.1 搭建博客 --构建标签
博客的每篇文章都是需要有标签的,它与文章也是多对多的关系 这篇笔记也是记录了实现标签的步骤逻辑. 在我们之前的笔记中创建了Tag的控制器和路由了 所以这篇笔记不在重复 1 创建模型与迁移文件 迁移文件 ...
- 深入了解Java之虚拟机内存
在讨论JVM内存区域分析之前,先来看一下Java程序详细运行的过程: -我们今天就来分析一下Java程序运行过程的-Runtime-Data-Area(运行时数据)-这一块" class=& ...
- spring基础---->spring自定义标签(一)
Spring具有一个基于架构的扩展机制,可以使用xml文件定义和配置bean.本博客将介绍如何编写自定义XML bean的解析器,并用实例来加以说明.其实我一直相信 等你出现的时候我就知道是你. Sp ...
- MySQL5.7压缩包安装图文教程
MySQL5.7压缩包安装图文教程 一.下载网址:https://dev.mysql.com/downloads/ 选择5.7版本 二.解压 下载完成后解压,解压后如下(zip是免安装的,解压后配置成 ...
- 各大网站CSS初始化代码集合
css代码之所以初始化,是因为能尽量减少 各浏览器之间的兼容性问题! 腾讯QQ官网 样式初始化 body,ol,ul,h1,h2,h3,h4,h5,h6,p,th,td,dl,dd,form,fiel ...
- 使用response来控制浏览器的缓存
缓存这个技术在我们实际的开发中是非常常用的,也是非常重要的一项技术.主要用于客户端(浏览器)向服务器端请求的是一些比较大的数据,并且这个数据在短时间内不会经常发生变化的情况,比如一些网站的logo图片 ...
- Exchange Database Status(Copy Status ,Content Index State,QueueLength,Move Status...)
Copy Status Description Mounted The active copy is online and accepting client connections. Only the ...