一、问题: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)

str是用来创建字符串对象的类,而int是用来创建整数对象的类,type 是type就是创建类对象的类,元类在API的定义中会有很大用处,具体内容在https://www.cnblogs.com/tkqasn/p/6524879.html讲得很清楚
Django的ORM 就是大量使用元类,有空研究一下。
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

三、挖坑

相关知识点:元类的使用以后研究

最新文章

  1. Get radio selected value
  2. java 在循环中删除数组元素
  3. Redis配置以及通过C#访问小试
  4. Tamperdata工具使用(登陆时就修改用户名),篡改post数据
  5. Hadoop集群(第10期)_MySQL关系数据库
  6. linux PCI设备初始化过程
  7. Flume 1.5日志收集和存款mongodb安装结构
  8. jquery设置select选中
  9. jQuery 最外面的那层皮
  10. asp.net mvc控制器激活全分析
  11. ubuntu 16.04 下安装动态链接库方法
  12. centos下mysql授予权限提示ERROR 1133 (42000): Can&#39;t find any matching row in the user table
  13. Java简介及开发环境配置
  14. Python encode() 方法(转)
  15. Flask web开发之路十
  16. 遍历所有子物体中renderer(渲染器)中的material(材质)并改变其alpha值实现若隐若现的效果
  17. C++ 关于MFC List Control 控件的使用事项 原创
  18. [转]Mahout推荐算法API详解
  19. 在Visual Studio中使用类图描述领域模型
  20. .NET:使用 XPATH 读取有 xmlns 属性的 XML 文档出现的问题

热门文章

  1. vm虚拟机中linux无法连接外网?
  2. CSS深入理解学习笔记之line-height
  3. 实现iota函数
  4. junit4X系列源码--Junit4 Runner以及test case执行顺序和源代码理解
  5. Spark 读写hive 表
  6. 一步一步从原理跟我学邮件收取及发送 9.多行结果与socket的阻塞
  7. linux僵尸进程
  8. 从零开始学习前端JAVASCRIPT — 10、JavaScript基础ES6(ECMAScript6.0)
  9. 玩转spring boot——国际化
  10. 利用回调实现Java的异步调用