Python 实现单例模式的一些思考
一、问题:Python中如何实现单例模式
单例模式指一个类只能实例化一个对象。
二、解决方案:
所有资料参考于:
http://python.jobbole.com/87294/
https://www.jianshu.com/p/f63ad9d550f1
https://www.cnblogs.com/tkqasn/p/6524879.html
1. 模块
永远只有一次,这让我下意识想到Python 的模块,因为学习的时候就知道,多次模块导入是无效的,都相当于导入一次,因为模块的导入十分消耗资源,若是重复导入那么太低效了。
因此可以利用 导入模块中的实例来实现这一目标。
#singleton.py
class SingleTon:
def demo(self):
print('hello world')
singleton = SingleTon() #test.py
from singleton import singleton
singleton.demo()
2. __new__方法
这里涉及到类实例化过程,我想,要想做到永远实例化一个对象,换句话说只要这个类实例化后就不再实例化,那么我们必须在Python原有实例化过程中“做点手脚”
那必要的就得现搞清楚实例化的具体过程。
首先:Foo类的类型是type,Foo 类 也是一个对象,实例化加括号即调用 __call__方法,而type 就是 Python 内置的元类,通过type类生成Foo类,
class Foo:
def __init__(self):
print('hello world')
item = Foo()
print(type(Foo),type(item))
#<class 'type'> <class '__main__.Foo'>
然后
Foo(*args, **kwargs)等价于Foo.__call__(*args, **kwargs)- 既然
Foo是一个type的实例,Foo.__call__(*args, **kwargs)实际调用的是type.__call__(Foo, *args, **kwargs) type.__call__(Foo, *args, **kwargs)调用type.__new__(Foo, *args, **kwargs),然后返回一个对象。obj随后通过调用obj.__init__(*args, **kwargs)被初始化。obj被返回。
可见,__new__() 方法是创建对象,__init__() 是初始化,若要解决我们的问题,应该在 前者下功夫,
class Foo:
_instance = None def __new__(cls, *args, **kwargs):
if cls._instance is None:
cls._instance = super().__new__(cls,*args,**kwargs)
return cls._instance item = Foo()
item1 = Foo()
print(item is item1)
3. 装饰器
使用装饰器应该也很方便,
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
wraps 函数 可以保证传入的类的属性不变,
4. 元类(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 实现单例模式的一些思考的更多相关文章
- 浅谈Python设计模式 - 单例模式
本篇主要介绍一下关于Python的单例模式,即让一个类对象有且只有一个实例化对象. 一.使用__new__方法(基类) 要实现单例模式,即为了让一个类只能实例化一个实例,那么我们可以去想:既然限制创建 ...
- 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的单例模式
原文:http://blog.csdn.net/ghostfromheaven/article/details/7671853 单例模式:保证一个类仅有一个实例,并提供一个访问他的全局访问点. 实现某 ...
- python实现单例模式
有这么一种场景,我们把数据封装到类体或类的某个方法里,然而我们new出这个类只是为了拿到这部分数据,那么当多次这样调用的时候,每次都来拿数据并放到内存中大大浪费了内存. 那我们就可以想,我们拿到一次数 ...
- python之单例模式、栈、队列和有序字典
一.单例模式 import time import threading class Singleton(object): lock = threading.RLock() # 定义一把锁 __inst ...
随机推荐
- BSA Network Shell系列-nexec | runcmd | runscript | scriptutil的异同
说明下nexec.runcmd.runscript.scriptutil的异同 相同点: 四者都可以在远程机器执行命令.或者调用脚本. 不同点: nexec支持NSH命令,可以执行远程机的本地命令(非 ...
- 如何用docker部署redis cluster
前言 由于本人是个docker控,不喜欢安装各种环境,而且安装redis-trib也有点繁琐,索性用docker来做redis cluster. 本文用的是伪集群,真正的集群放到不同的机器即可.端口是 ...
- 关于Mysql模糊查询的优化-全文检索和Like的使用
表A:CREATE TABLE `tableA` (`id` int(11) NOT NULL auto_increment,`content` varchar(256) default NULL,P ...
- html5中的新标签
header <header> 标签定义文档的页眉(介绍信息). nva 根据W3C的定义规范:nav元素是一个可以用来作为页面导航的链接组: <nav><ul>& ...
- python 编写简单的setup.py
学习python也已经有一段时间了,发现python作为脚本语言一个很重要的特点就是简单易用,而且拥有巨多的第三方库,几乎方方面面的库都有,无论你处于哪个行业,想做什么工作,几乎都能找到对应的第三方库 ...
- Java - 二叉树递归与非递归
树的定义具有递归特性,因此用递归来遍历比较符合特性,但是用非递归方式就比较麻烦,主要是递归和栈的转换. import java.util.Stack; /** * @author 李文浩 * @ver ...
- (三)surging 微服务框架使用系列之我的第一个服务(审计日志)
前言:前面准备了那么久的准备工作,现在终于可以开始构建我们自己的服务了.这篇博客就让我们一起构建自己的第一个服务---审计日志. 首先我们先创建两个项目,一个控制台的服务启动项目,一个业务的实现项目. ...
- JS前端验证代码
手机号码正则表达式验证: function checkPhone(){ var phone = document.getElementById('phone').value; if(!(/^1[345 ...
- 分布式唯一id:snowflake算法思考
匠心零度 转载请注明原创出处,谢谢! 缘起 为什么会突然谈到分布式唯一id呢?原因是最近在准备使用RocketMQ,看看官网介绍: 一句话,消息可能会重复,所以消费端需要做幂等.为什么消息会重复后续R ...
- java 世界中Annotation
java 世界中Annotation 在github上开始汇总一些自己学习,收集,总结,经验的一些信息,有利于跟踪,修改,提升.如果你感兴趣 可以关注一下,也可以提供自己的内容进来. https:// ...