单例模式(Singleton Pattern)是一种常用的软件设计模式,该模式的主要目的是确保某一个类只有一个实例存在。当你希望在整个系统中,某个类只能出现一个实例时,单例对象就能派上用场。

在 Python 中,我们可以用多种方法来实现单例模式:

  • 使用模块
  • 使用 __new__
  • 使用装饰器(decorator)
  • 使用元类(metaclass)

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()

使用 __new__

为了使类只能出现一个实例,我们可以使用 __new__ 来控制实例的创建过程,代码如下:

class Singleton(object):
_instance = None
def __new__(cls, *args, **kw):
if not cls._instance:
cls._instance = super(Singleton, cls).__new__(cls, *args, **kw)
return cls._instance class MyClass(Singleton):
a = 1

使用装饰器:

我们知道,装饰器(decorator)可以动态地修改一个类或函数的功能。这里,我们也可以使用装饰器来装饰某个类,使其只能生成一个实例,代码如下:

from functools import wraps

def singleton(cls):
instances = {}
@wraps(cls)
def getinstance(*args, **kw):
if cls not in instances:
instances[cls] = cls(*args, **kw)
return instances[cls]
return getinstance @singleton
class MyClass(object):

在上面,我们定义了一个装饰器 singleton,它返回了一个内部函数 getinstance,该函数会判断某个类是否在字典 instances 中,如果不存在,则会将 cls 作为 key,cls(*args, **kw) 作为 value 存到 instances 中,否则,直接返回 instances[cls]

使用 metaclass

元类(metaclass)可以控制类的创建过程,它主要做三件事:

  • 拦截类的创建
  • 修改类的定义
  • 返回修改后的类

使用元类实现单例模式的代码如下:

class Singleton(type):
_instances = {}
def __call__(cls, *args, **kwargs):
if cls not in cls._instances:
cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs)
return cls._instances[cls] # Python2
class MyClass(object):
__metaclass__ = Singleton # Python3
# class MyClass(metaclass=Singleton):
# pass

Python 高级编程——单例模式的更多相关文章

  1. python高级编程:有用的设计模式1

    # -*- coding: utf-8 -*-__author__ = 'Administrator'#python高级编程:有用的设计模式#设计械是可复用的,某种程序上它对软件设计中觉问题提供的语言 ...

  2. python高级编程读书笔记(一)

    python高级编程读书笔记(一) python 高级编程读书笔记,记录一下基础和高级用法 python2和python3兼容处理 使用sys模块使程序python2和python3兼容 import ...

  3. python高级编程:有用的设计模式3

    # -*- coding: utf-8 -*-__author__ = 'Administrator'#python高级编程:有用的设计模式#访问者:有助于将算法从数据结构中分离出来"&qu ...

  4. python高级编程:有用的设计模式2

    # -*- coding: utf-8 -*- __author__ = 'Administrator' #python高级编程:有用的设计模式 #代理 """ 代理对一 ...

  5. python高级编程技巧

    由python高级编程处学习 http://blog.sina.com.cn/s/blog_a89e19440101fb28.html Python列表解析语法[]和生成 器()语法类似 [expr  ...

  6. python高级编程之选择好名称:完

    由于时间关系,python高级编程不在放在这边进行学习了,如果需要的朋友可以看下面的网盘进行下载 # # -*- coding: utf-8 -*- # # python:2.x # __author ...

  7. python高级编程之列表推导式

    1. 一个简单的例子 在Python中,如果我们想修改列表中所有元素的值,可以使用 for 循环语句来实现. 例如,将一个列表中的每个元素都替换为它的平方: >>> L = [1, ...

  8. Python高级编程之生成器(Generator)与coroutine(二):coroutine介绍

    原创作品,转载请注明出处:点我 上一篇文章Python高级编程之生成器(Generator)与coroutine(一):Generator中,我们介绍了什么是Generator,以及写了几个使用Gen ...

  9. Python高级编程-Python一切皆对象

    Python高级编程-Python一切皆对象 Python3高级核心技术97讲 笔记 1. Python一切皆对象 1.1 函数和类也是对象,属于Python的一等公民 ""&qu ...

随机推荐

  1. Python之路(第十二篇)程序解耦、模块介绍\导入\安装、包

    一.程序解耦 解耦总的一句话来说,减少依赖,抽象业务和逻辑,让各个功能实现独立. 直观理解“解耦”,就是我可以替换某个模块,对原来系统的功能不造成影响.是两个东西原来互相影响,现在让他们独立发展:核心 ...

  2. idea窗口下方滚动条不明显设置

    在使用idea时,下方的滚动条老是显示不明显,每次点击拖拽都很费劲,在网上找了很多相关设置,最后确定了一个最好的办法解决问题: Shift (上档) +  鼠标滚动,这样就可以横向翻滚了,很方便 此方 ...

  3. ubuntu系统ftp连接 以及ssh连接

    tfp连接 ssh连接 ubuntu下ssh使用 与 SCP 使用 1 ssh远程登录服务器 ssh username@remote_ip #将username换成自己的用户名,将remote_ip换 ...

  4. m序列

    产生m序列移位寄存器是一种逻辑电路,1阶,2阶...的电路图各不相同. 一般使用本原多项式计算出各阶数电路图. 一般的多项式为 f(x) = c0 * x^0 + c1 * x^1 + c2 * x^ ...

  5. 熟悉JSON

    JSON是什么 JSON ( JavaScript Object Notation) ,是一种数据交互格式. 为什么有这个技术 Json之前,大家都用 XML 传递数据.XML 是一种纯文本格式,所以 ...

  6. JSON文件导入Unity3d中是空的的问题

    将Json文件的内容在网上在线的Json文件编辑器导出后再导入即可

  7. python对数据类型的相关操作

    一.int的相关操作 int只有一个相关操作,bit_length()   用于计算一个数字的二进制长度 二.bool的相关操作 1.把数字转换成bool,除了0,返回的都是True a = 10 p ...

  8. 2018.10.29 洛谷P4129 [SHOI2006]仙人掌(仙人掌+高精度)

    传送门 显然求出每一个环的大小. Ans=∏i(siz[i]+1)Ans=\prod_i(siz[i]+1)Ans=∏i​(siz[i]+1) 注意用高精度存答案. 代码: #include<b ...

  9. 更新源pip

    国内镜像源列表 豆瓣(douban) http://pypi.douban.com/simple/清华大学 https://pypi.tuna.tsinghua.edu.cn/simple/阿里云 h ...

  10. mongodb知识积累

    1: 安装mongodb https://www.cnblogs.com/zhangdaicong/p/7492494.html 2:配置文件 vi /etc/mongodb.conf https:/ ...