单例模式

单例模式(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()

 

最新文章

  1. 从零开始编写自己的C#框架(11)——创建解决方案
  2. 自定义UI集成微信、QQ、微博分享功能
  3. [原创]在Linux系统Ubuntu14.04上安装部署docker。
  4. delphi IOS 获取电池信息
  5. css各项水平居中
  6. python学习 函数
  7. 开篇&TexturePacker打出图集给UGUI使用
  8. 史上最全的RunLoop介绍
  9. 【服务器防护】VPN的ip变更,导致无法连接服务器,解决方法【阿里云ECS】
  10. ajax 传参 乱码问题
  11. CC.NET模板简化配置
  12. declare 命令
  13. STL中坑爹的max函数
  14. laravel 配置MySQL读写分离
  15. 《深入理解Nginx:模块开发与架构解析》读书笔记
  16. 20165327 2017-2018-2 《Java程序设计》第8周学习总结
  17. Arduino驱动无源蜂鸣器发声
  18. SQL 报表 --简易进销系统
  19. Python的静态方法和类成员方法
  20. Build IKAnalyzer With Solr 5.1.0

热门文章

  1. 28Mybatis_查询缓存-二级缓存-二级缓存测试-
  2. 让div也出现滑动框。
  3. epplus excel数据导出(数据量有点大的情况) Web和Client
  4. Iframe 父子窗体互调javascript方法及相互获取控件
  5. UESTC 1511(差分约束)
  6. JQuery------实现鼠标点击和滑动不同效果
  7. 获取本地的json并展示
  8. iOS-多线程的底层实现
  9. VMware虚拟机下安装CentOS7.0超详细图文教程
  10. SaltStack之编译安装LNMP环境