聊一聊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 ...
随机推荐
- php -- PDO预处理
可以使用多种方式实现预处理:指的是在绑定数据进行执行的时候,可以有多种方式. 预处理语句中为变量 使用数组指定预处理变量 1.准备预处理语句(发送给服务器,让服务器准备预处理语句) PDOStatem ...
- linux基础教程---内容操作
一.寻找文件里的指定内容 寻找文件里的指定内容,输出内容所在行的所有信息 grep 被搜索内容 文件路径名 >grep var passwd //在 ...
- 《随机出题软件》&《随机分队软件》源码(Windows API)
1 引言 1.1 编写目的: 为了对院级活动<最强大脑>提供软件支持,同时为了练习使用windows API. 1.2 项目背景: 来自计算机学院学生会信息部指派的任务,规定时间完成软件的 ...
- Spring Cache 自定义注解
1.在使用spring cache注解如cacheable.cacheevict.cacheput过程中有一些问题: 比如,我们在查到一个list后,可以将list缓存到一个键对应的区域里:当新增.修 ...
- 转:解决Python2.7的UnicodeEncodeError: ‘ascii’ codec can’t encode异常错误
操作SQL数据库,Python使用的是版本2.7,但是在运行的时候出现了异常错误UnicodeEncodeError:'ascii' codec can't encode characters in ...
- 打印出现:You've implemented -[<UIApplicationDelegate> application:didReceiveRemoteNotification:
解决办法: 第一种:Product -> Target -> Capabilities -> Background Modes -> 勾选Remote notification ...
- TFS 创建团队成员及管理
用TFS服务器管理代码 1:创建TFS服务器 2:创建TFS项目 3:创建TFS团队成员 4:上传代码,共享链接,对代码进行管理 这里主要介绍第三步:创建TFS团队成员 第一种:通过连接进入TFS可视 ...
- 【BZOJ4808/3175】马/[Tjoi2013]攻击装置 最小割
[BZOJ4808]马 Description 众所周知,马后炮是中国象棋中很厉害的一招必杀技."马走日字".本来,如果在要去的方向有别的棋子挡住(俗称"蹩马腿" ...
- 单台centos7.3 虚拟机实现主从复制和哨兵集群
环境: centos7.3一台 部署图: 从服务器配置: slaveof 哨兵配置: port sentinel monitor m1 127.0.0.1 6379 2 sentinel monito ...
- Code Forces 20A BerOS file system
A. BerOS file system time limit per test 2 seconds memory limit per test 64 megabytes input standard ...