聊一聊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 ...
随机推荐
- 一个线程可以拿到多个锁标记,一个对象最多只能将monitor给一个线程
当用Synchronized修饰某个方法的时候,表示该方法都对当前对象加锁. 给方法加Synchronized和用Synchronized修饰对象的效果是一致的. 一个线程可以拿到多个锁标记,一个对象 ...
- ubuntu16.04 安装 eclipse
1. 下载jdk , jdk-8u77-Linux-x64.tar.gz 2.下载 eclipse , eclipse-jee-mars-2-linux-gtk-x86_64.tar.gz 注:我下 ...
- js math atan2
在双十二活动中,视觉要求实现一个鼠标跟随运动的的效果,就像“觉”的那个效果类似 其实原理很简单,看鼠标从哪个方向进的及从哪个方向出的,然后区块里绝对定位的浮层就可以根据鼠标方向 运动; 如:在鼠标进入 ...
- LoadRunner检查点实战之运行查看器
一.为什么要使用检查点 为什么要使用检查点,那就要说明一下LR如何判断脚本是否执行成功.LR判断脚本是否执行成功是根据服务器返回的状态来确定的,如果服务器返回的HTTP状态为 200 OK ,那么Vu ...
- 深入.net调用webservice的总结分析
最近做一个项目,由于是在别人框架里开发app,导致了很多限制,其中一个就是不能直接引用webservice .我们都知道,调用webserivice 最简单的方法就是在 "引用" ...
- iOS开发之--TableViewCell重用机制避免重复显示问题
常规配置如下 当超过tableView显示的范围的时候 后面显示的内容将会和前面重复 // 这样配置的话超过页面显示的内容会重复出现 - (UITableViewCell *)tableView:(U ...
- 解决ScrollView滑动RecyclerView的卡顿
我们不的不了解ViewConfiguration这个类,官方是这么解释的Contains methods to standard constants used in the UI for timeou ...
- JSP内置对象——response
response对象response对象包含了响应客户端的有关信息,但在JSP中很少使用它.它是HttpServletResponse类的实例.response对象具有页面作用域,即访问一个页面时,该 ...
- JZOJ.5327【NOIP2017模拟8.21】四驱兄弟
Description
- PMP 质量管理新7张图
亲和图.关联图.系统图.矩阵图.网络图.pdpc.矩阵数据分析法