聊一聊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 ...
随机推荐
- 当心文件 I/O 有错误
当心文件 I/O 有错误. #include <iostream> #include <iostream> #include <numeric> #include ...
- bootstrap基础学习七篇
bootstrap图片 Bootstrap 提供了三个可对图片应用简单样式的 class: .img-rounded:添加 border-radius:6px 来获得图片圆角. .img-circle ...
- ThinkPHP项目笔记之RBAC(权限)补充篇
这里,主要补充的是配置以及相关代码问题. <?php return array( //'配置项'=>'配置值' 'RBAC_SUPERADMIN' => 'admin',//超级管理 ...
- SQLserver 设置自增为显式插入
默认是状态是set IDENTITY_INSERT T2 off ,就是关闭了自动插入值的功能,为空时就会报错 ,,'') 报错: 消息 544,级别 16,状态 1,第 1 行当 IDENTITY_ ...
- 运动目标检测ViBe算法
一.运动目标检测简介 视频中的运动目标检测这一块现在的方法实在是太多了.运动目标检测的算法依照目标与摄像机之间的关系可以分为静态背景下运动检测和动态背景下运动检测.先简单从视频中的背景类型来讨论. ...
- 杭电 1280 前m大的数
http://acm.hdu.edu.cn/showproblem.php?pid=1280 前m大的数 Time Limit: 2000/1000 MS (Java/Others) Memor ...
- 第二十一篇:Linux 操作系统中的进程结构
前言 在 Linux 中,一个正在执行的程序往往由各种各样的进程组成,这些进程除了父子关系,还有其他的关系.依赖于这些关系,所有进程构成一个整体,给用户提供完整的服务( 考虑到了终端,即与用户的交互 ...
- java基础---->string字面量的使用
这里简单的理解一下java中关于string字面量的知识,关于字节码可以使用java自带的javap工具查看. string字面量 一.直接贴出测试的代码 A string literal alway ...
- centos7上面安装MySQL
date:2018-04-03 14:07:54 本文摘自网上,经本人整理后如下:原作者及出处为: [日期:2016-09-18] 来源:Linux社区 作者:xyang81 1.配置YUM源 下 ...
- 怎么在android实现通过浏览器点击链接打开apk
intent://scan/#Intent;scheme=appname://appname/[频道]/[id];package=com.appname.package;end http://m.ch ...