python中的单例模式实现
什么是单例模式
单例模式是⼀种经常使⽤的设计模式,使⽤该模式创建的类对象在整个系统中只有⼀个。在python中,使⽤id(实例名)可以看到多次创建该类的对象的id是相同的
什么时候适合使⽤单例模式
简⽽⾔之⼀句话,需要节省内存,加快对象访问速度以及对象需要被公⽤的场合
单例模式使⽤场景
1. 系统中配置⽂件的管理
2. ⽹站中的计数器
3. 应⽤程序的⽇志应⽤
4. 等等。。。
python中单例模式的实现
1. 通过模块实现单例模式(最简单的实现⽅式)
原理:python的模块其实是⼀个⾮常好的⾃带单例模式,python的模块在导⼊时会⽣成.pyc⽂件,在后⾯再次导⼊该模块时,会加载.pyc⽂件
代码⽰例:
# -*- coding: utf-8 -*-
class Singleton(object):
pass
s = Singleton()
上述⽂件中就存在了⼀个Singleton类的实例s,在使⽤时,通过from singleton import s导⼊这个实例,就可以获得这个使⽤这个单例,同时它也是⼀个单例模式的对象
2. 通过改写__new__⽅法实现(推荐使⽤该⽅法)
原理:在python的类创建对象的过程中,先通过__new__⽅法实例化⼀个对象(PS:在没有⾃⼰定义
该⽅法时会默认调⽤
代码⽰例:
class Singleton(object):
_lock = threading.Lock()
def__new__(cls,*args,**kwargs):
if not hasattr(Singleton,"_instance"):
with Singleton._lock:# 加锁防⽌多线程环境中两个线程同时判断到上⼀⾏代码为True,同时创建该类的实例
if not hasattr(Singleton,"_instance"):
# 调⽤object类的__new__⽅法
Singleton._instance =super(Singleton, cls).__new__(cls,*args,**kwargs)
return Singleton._instance
def test(number):
单例模式的几种实现方式s = Singleton()
print str(number)+": "+str(id(s))
for i in range(10):
t = threading.Thread(target=test, args=(i,))
t.start()
上述程序运⾏结果如下:
3. 基于指定metaclass实现
原理:这个解释起来源远流长,可以针对元类单独写⼀篇博客了,这⾥就简单说明⼀下。类其实也是⼀个对象,创建类的类就是元类,⼤致可以理解为:MyClass = MetaClass(),MyObject = MyClass(),其中MetaClass就是⼀个元类,是创建MyClass这个实例(对于MyObject来说它⼜是⼀个类,注意区别理解)的类。在python中默认的元类是⼀个强⼤的函数type。
代码⽰例:
# 注意这⾥继承了type不是object
class SingletonMeta(type):
_lock = threading.Lock()
def__init__(self,*args,**kwargs):
super(SingletonMeta, self).__init__(*args,**kwargs)
def__call__(cls,*args,**kwargs):
if not hasattr(cls,"_instance"):
with SingletonMeta._lock:
if not hasattr(cls,"_instance"):
cls._instance =super(SingletonMeta, cls).__call__(*args,**kwargs) return cls._instance
class Singleton:
__metaclass__ = SingletonMeta    # 指定元类
def__init__(self, x):
self.x = x
def test(number):
s = Singleton(number)
print str(number)+": "+str(id(s))
for i in range(10):
t = threading.Thread(target=test, args=(i,))
t.start()
结果如下所⽰:
4. 使⽤装饰器
相关知识:装饰器的使⽤⽅法类似java中的注解,⼤概形式如下:
def log(func):
def wrapper(*args,**kwargs):
return func(*args,**kwargs)
return log
@log
def f():
pass
实际上述f函数执⾏过程变为f=log(f), f()
代码⽰例:
# -*- coding: utf-8 -*-
import threading
def Singleton(cls):
_instance ={}
def_singleton(*args,**kwargs):
if cls not in _instance:
_instance[cls]= cls(*args,**kwargs)
return _instance[cls]
return _singleton
@Singleton
class A(object):
a =1
def__init__(self, x=0):
self.x = x
a1 = A(2)
a2 = A(3)
print a1 == a2
5. 使⽤类
原理:使⽤类成员,类成员是该类所有实例共有的属性
代码⽰例:
# -*- coding: utf-8 -*-
import threading
class Singleton(object):
_lock = threading.Lock()
@classmethod
def generate(cls,*args,**kwargs):
with Singleton._lock:
if not hasattr(Singleton,"_instance"):
Singleton._instance = Singleton(*args,**kwargs) return Singleton._instance
def test(number):
s = ate()
print str(number)+": "+str(id(s))
for i in range(10):
t = threading.Thread(target=test, args=(i,))
t.start()
执⾏结果如下:

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。