Python中的单例模式
在 Python 中,我们可以用多种方法来实现单例模式:
- 使用模块
- 使用
__new__ - 使用装饰器(decorator)
- 使用元类(metaclass)
# mysingleton.py
class My_Singleton(object):
def foo(self):
pass
my_singleton = My_Singleton() ##############调用
from mysingleton import my_singleton my_singleton.foo()
使用 __new__
为了使类只能出现一个实例,我们可以使用 __new__ 来控制实例的创建过程
class Singleton(object):
_instance = None
def __new__(cls, *args, **kwargs):
if not cls._instance:
cls._instance = super(Singleton, cls).__new__(cls, *args, **kwargs)
return cls._instance class MyClass(Singleton):
c = 1 a=MyClass()
b=MyClass()
print(a==b)
print(a is b)
print(id(a),id(b))
"""
True
True
1947813794256 1947813794256
"""
edition 2
class Singleton(object):
def __new__(cls, *args, **kw):
if not hasattr(cls, '_instance'):
orig = super(Singleton, cls)
cls._instance = orig.__new__(cls, *args, **kw)
return cls._instance class MyClass(Singleton):
a = 1 a=MyClass()
b=MyClass()
print(a==b)
print(a is b)
print(id(a),id(b))
共享属性
创建实例时把所有实例的__dict__指向同一个字典,这样它们具有相同的属性和方法.
class Borg(object):
_state = {}
def __new__(cls, *args, **kw):
# ob = super(Borg, cls).__new__(cls, *args, **kw)
cls._state[cls]= super(Borg, cls).__new__(cls, *args, **kw)
cls._state[cls].__dict__ = cls._state
print(cls._state)
print(cls) class MyClass(Borg):
a = 1 a=MyClass()
b=MyClass()
print(a==b)
print(a is b)
print(id(a),id(b))
print(MyClass.__dict__)
"""
{<class '__main__.MyClass'>: <__main__.MyClass object at 0x000001E31655D940>}
<class '__main__.MyClass'>
{<class '__main__.MyClass'>: <__main__.MyClass object at 0x000001E31656F940>}
<class '__main__.MyClass'>
True
True
1438393552 1438393552
{'__module__': '__main__', 'a': 1, '__doc__': None}
"""
装饰器(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):
a = 1 a=MyClass()
b=MyClass()
print(a==b)
print(a is b)
print(id(a),id(b))
在上面,我们定义了一个装饰器 singleton,它返回了一个内部函数 getinstance,该函数会判断某个类是否在字典 instances 中,如果不存在,则会将 cls 作为 key,cls(*args, **kw) 作为 value 存到 instances 中,否则,直接返回 instances[cls]。
也可以是:
def singleton(cls, *args, **kw):
instances = {}
def getinstance():
if cls not in instances:
instances[cls] = cls(*args, **kw)
return instances[cls]
return getinstance @singleton
class MyClass:
a=1
使用 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 a=MyClass()
b=MyClass()
print(a==b)
print(a is b)
print(id(a),id(b))
Python 的模块是天然的单例模式,这在大部分情况下应该是够用的,当然,我们也可以使用装饰器、元类等方法
Python中的单例模式的更多相关文章
- Python学习笔记之在Python中实现单例模式
有些时候你的项目中难免需要一些全局唯一的对象,这些对象大多是一些工具性的东西,在Python中实现单例模式并不是什么难事.以下总结几种方法: 使用类装饰器 使用装饰器实现单例类的时候,类本身并不知道自 ...
- Python中的单例模式的几种实现方式的优缺点及优化
单例模式 单例模式(Singleton Pattern)是一种常用的软件设计模式,该模式的主要目的是确保某一个类只有一个实例存在.当你希望在整个系统中,某个类只能出现一个实例时,单例对象就能派上用场. ...
- Python 中的单例模式
单例模式 单例模式(Singleton Pattern)是一种常用的软件设计模式,该模式的主要目的是确保某一个类只有一个实例存在.当你希望在整个系统中,某个类只能出现一个实例时,单例对象就能派上用场. ...
- Python中的单例模式——装饰器实现剖析
Python中单例模式的实现方法有多种,但在这些方法中属装饰器版本用的广,因为装饰器是基于面向切面编程思想来实现的,具有很高的解耦性和灵活性. 单例模式定义:具有该模式的类只能生成一个实例对象. 先将 ...
- python中的单例模式、元类
单例模式 单例模式(Singleton Pattern)是一种常用的软件设计模式,该模式的主要目的是确保某一个类只有一个实例存在.当你希望在整个系统中,某个类只能出现一个实例时,单例对象就能派上用场. ...
- Python中的单例模式的几种实现方式的及优化
单例模式 单例模式(Singleton Pattern)是一种常用的软件设计模式,该模式的主要目的是确保某一个类只有一个实例存在.当你希望在整个系统中,某个类只能出现一个实例时,单例对象就能派上用场. ...
- python中实现单例模式
单例模式的目的是一个类有且只有一个实例对象存在,比如在复用类的过程中,可能重复创建多个实例,导致严重浪费内存,此时就适合使用单例模式. 前段时间需要用到单例模式,就称着机会在网上找了找,有包含了__n ...
- python中的单例模式的应用
1 使用__new__方法 class Singleton(object): def __new__(cls, *args, **kw): if not hasattr(cls, ...
- Python中的单例模式的几种实现方式和优化以及pyc文件解释(转)
原文:https://www.cnblogs.com/huchong/p/8244279.html 另一篇关于.pyc文件是什么? 原文: http://blog.sina.com.cn//s/bl ...
随机推荐
- jfinal使用jstl表达的存在的问及解决
问题 使用jstl 的el表达式 传递数据刷新页面,页面数据不显示,经过验证,数据的确传递过去,但是官方文档并没有详细描述,getModel() 不需要设get set() ,但是使用jstl el表 ...
- 《剑指Offer》面试题5-替换空格
题目:请实现一个函数,把字符串中的每个空格替换成"%20".例如输入"We are happy.",则输出"We%20are%20happy.&quo ...
- 在centos6上实现LAMP的FPM模式
原理 http使用一次编译法编译安装,php独立服务fpm实现. 软件版本 在本次实验中,我们需要用到的软件版本如下: apr-1.6.2 apr-util-1.6.0 httpd-2.4.28 ma ...
- EF异常探究(An entity object cannot be referenced by multiple instances of IEntityChangeTracker.)
今天在改造以前旧项目时出现了一项BUG,是由于以前不规范的EF写法所导致.异常信息如下: "An entity object cannot be referenced by multiple ...
- PHP设计模式二:单例模式
一.什么是单例模式 作为对象的创建模式,单例模式确保某一个类只有一个实例,并且对外提供这个全局实例的访问入口.它不会 创建实例副本,而是会向单例类内部存储的实例返回一个引用. 二.PHP单例模式三要素 ...
- ASP.NET Core 开源GitServer 实现自己的GitHub
ASP.NET Core 2.0 开源Git HTTP Server,实现类似 GitHub.GitLab. GitHub:https://github.com/linezero/GitServer ...
- abapGit分支策略
各位ABAP公民们.特别是使用abapGit的各位,你们好. 我的团队和我将向大家分享我公司内引入abapGit后产生的某些开发问题.我所在的公司是一家创作SAP第三方软件的公司,目前主要使用ABAP ...
- 【深度学习系列】手写数字识别卷积神经--卷积神经网络CNN原理详解(一)
上篇文章我们给出了用paddlepaddle来做手写数字识别的示例,并对网络结构进行到了调整,提高了识别的精度.有的同学表示不是很理解原理,为什么传统的机器学习算法,简单的神经网络(如多层感知机)都可 ...
- [译]ASP.NET Core 2.0 路由引擎
问题 ASP.NET Core 2.0的路由引擎是如何工作的? 答案 创建一个空项目,为Startup类添加MVC服务和请求中间件: public void ConfigureServices(ISe ...
- java语言在某个数组中查找某个字符出现的次数
package com.llh.demo; import java.util.Scanner; /** * * @author llh * */ public class Test { /* * 在某 ...