Python 实现单例模式的一些思考
2018-03-09 18:10
417 查看
一、问题:Python中如何实现单例模式
单例模式指一个类只能实例化一个对象。
二、解决方案:
所有资料参考于:
http://python.jobbole.com/87294/
https://www.jianshu.com/p/f63ad9d550f1
https://www.cnblogs.com/tkqasn/p/6524879.html
1. 模块
永远只有一次,这让我下意识想到Python 的模块,因为学习的时候就知道,多次模块导入是无效的,都相当于导入一次,因为模块的导入十分消耗资源,若是重复导入那么太低效了。
因此可以利用 导入模块中的实例来实现这一目标。
new方法
这里涉及到类实例化过程,我想,要想做到永远实例化一个对象,换句话说只要这个类实例化后就不再实例化,那么我们必须在Python原有实例化过程中“做点手脚”
那必要的就得现搞清楚实例化的具体过程。
首先:Foo类的类型是type,Foo 类 也是一个对象,实例化加括号即调用 call方法,而type 就是 Python 内置的元类,通过type类生成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() 是初始化,若要解决我们的问题,应该在 前者下功夫,
装饰器
使用装饰器应该也很方便,wraps 函数 可以保证传入的类的属性不变,
元类(metaclass)
str是用来创建字符串对象的类,而int是用来创建整数对象的类,type 是type就是创建类对象的类,元类在API的定义中会有很大用处,具体内容在https://www.cnblogs.com/tkqasn/p/6524879.html讲得很清楚
Django的ORM 就是大量使用元类,有空研究一下。
三、挖坑
相关知识点:元类的使用以后研究
单例模式指一个类只能实例化一个对象。
二、解决方案:
所有资料参考于:
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()
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)
装饰器
使用装饰器应该也很方便,wraps 函数 可以保证传入的类的属性不变,
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
元类(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
三、挖坑
相关知识点:元类的使用以后研究
相关文章推荐
- 关于C++中实现单例模式的一些思考
- 单例模式与全局唯一id的思考----c++ ,c ,python 实现
- NTLM挑战模式散列认证加密协议过程,算法实现与一些想法
- 一些个人的思考:收索引擎与保护模式下的物理地址生成
- 关于linux中nat实现的一些思考
- [原创]对linux fork工作模式(python版)的一些理解
- 关于linux中nat实现的一些思考
- Abstract Factory设计模式的一些思考
- PHP中实现ActiveRecord模式的一些项目总结
- 内存池完整实现代码及一些思考
- python 的一些思考(字符,django,动态语言)
- 内存池完整实现代码及一些思考
- Head First 设计模式——策略模式(Strategy Pattern)——Python实现
- Head First 设计模式——观察者模式(Observer Pattern)——Python实现(1)
- 用Python的类变量实现单一模式
- 关于选用Python IDE的一些思考
- 观察者模式 python实现
- 设计模式2思考——web框架中—页面功能设计的实现
- reportviewer动态加载报表的实现以及动态控制报表,套打,存折打印模式等的一些探讨,欢迎批评指正!
- MSSQL显错模式的手工注入实现原理思考和实战