单例模式

单例模式(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的单例模式的更多相关文章

  1. python实现单例模式的三种方式及相关知识解释

    python实现单例模式的三种方式及相关知识解释 模块模式 装饰器模式 父类重写new继承 单例模式作为最常用的设计模式,在面试中很可能遇到要求手写.从最近的学习python的经验而言,singlet ...

  2. Python 基于python实现单例模式

    基于python实现单例模式 by:授客 QQ:1033553122   概念 简单说,单例模式(也叫单件模式)的作用就是保证在整个应用程序的生命周期中,任何一个时刻,单例类的实例都只存在一个(当然也 ...

  3. python 以单例模式封装logging相关api实现日志打印类

    python 以单例模式封装logging相关api实现日志打印类   by:授客QQ:1033553122 测试环境: Python版本:Python 2.7   实现功能: 支持自由配置,如下lo ...

  4. python的单例模式:

    python的单例模式:http://funhacks.net/2017/01/17/singleton/ https://www.cnblogs.com/huchong/p/8244279.html ...

  5. 【Python】单例模式Singleton

    前两天一个面试被问到python中单例模式有几种实现方式,只答出了可以用元类实现...然后就想不起来了. 之后翻书,原来这些之前都见过的啊.... 1.手动实现真正创建实例的方法__new__()来实 ...

  6. 浅谈Python设计模式 - 单例模式

    本篇主要介绍一下关于Python的单例模式,即让一个类对象有且只有一个实例化对象. 一.使用__new__方法(基类) 要实现单例模式,即为了让一个类只能实例化一个实例,那么我们可以去想:既然限制创建 ...

  7. 【python】Python的单例模式

    原文:http://blog.csdn.net/ghostfromheaven/article/details/7671853 单例模式:保证一个类仅有一个实例,并提供一个访问他的全局访问点. 实现某 ...

  8. python实现单例模式

    有这么一种场景,我们把数据封装到类体或类的某个方法里,然而我们new出这个类只是为了拿到这部分数据,那么当多次这样调用的时候,每次都来拿数据并放到内存中大大浪费了内存. 那我们就可以想,我们拿到一次数 ...

  9. Python 实现单例模式的一些思考

    一.问题:Python中如何实现单例模式 单例模式指一个类只能实例化一个对象. 二.解决方案: 所有资料参考于: http://python.jobbole.com/87294/ https://ww ...

随机推荐

  1. 一个线程可以拿到多个锁标记,一个对象最多只能将monitor给一个线程

    当用Synchronized修饰某个方法的时候,表示该方法都对当前对象加锁. 给方法加Synchronized和用Synchronized修饰对象的效果是一致的. 一个线程可以拿到多个锁标记,一个对象 ...

  2. ubuntu16.04 安装 eclipse

    1. 下载jdk , jdk-8u77-Linux-x64.tar.gz 2.下载 eclipse  , eclipse-jee-mars-2-linux-gtk-x86_64.tar.gz 注:我下 ...

  3. js math atan2

    在双十二活动中,视觉要求实现一个鼠标跟随运动的的效果,就像“觉”的那个效果类似 其实原理很简单,看鼠标从哪个方向进的及从哪个方向出的,然后区块里绝对定位的浮层就可以根据鼠标方向 运动; 如:在鼠标进入 ...

  4. LoadRunner检查点实战之运行查看器

    一.为什么要使用检查点 为什么要使用检查点,那就要说明一下LR如何判断脚本是否执行成功.LR判断脚本是否执行成功是根据服务器返回的状态来确定的,如果服务器返回的HTTP状态为 200 OK ,那么Vu ...

  5. 深入.net调用webservice的总结分析

    最近做一个项目,由于是在别人框架里开发app,导致了很多限制,其中一个就是不能直接引用webservice .我们都知道,调用webserivice 最简单的方法就是在 "引用"  ...

  6. iOS开发之--TableViewCell重用机制避免重复显示问题

    常规配置如下 当超过tableView显示的范围的时候 后面显示的内容将会和前面重复 // 这样配置的话超过页面显示的内容会重复出现 - (UITableViewCell *)tableView:(U ...

  7. 解决ScrollView滑动RecyclerView的卡顿

    我们不的不了解ViewConfiguration这个类,官方是这么解释的Contains methods to standard constants used in the UI for timeou ...

  8. JSP内置对象——response

    response对象response对象包含了响应客户端的有关信息,但在JSP中很少使用它.它是HttpServletResponse类的实例.response对象具有页面作用域,即访问一个页面时,该 ...

  9. JZOJ.5327【NOIP2017模拟8.21】四驱兄弟

    Description

  10. PMP 质量管理新7张图

    亲和图.关联图.系统图.矩阵图.网络图.pdpc.矩阵数据分析法