python下的单例模式
2017-06-21
单例模式
何为单例模式?
单例模式是一种设计模式, 表示针对某类的实例, 有且仅会有单个实例对象会被创建, 这样, 进程在运行过程中, 在任何地方得到的这个类的实例总是共享的
应用场景
比如redis的连接实例, 数据库的连接实例等等, 在进程运行过程中, 我们不希望多次创建连接实例, 这时就可以使用单例
单例实现
那么, 在python里如何创建单例呢
在类实例前, 会调用一个内置的函数__new__
, 我们可以通过修改这个函数, 来保证实例化的结果总是同一个实例
__new__ 实现单例
class S(object):
def __new__(cls):
if hasattr(cls, 'ins'):
return getattr(cls, 'ins')
instance = object.__new__(cls)
cls.ins = instance
return instance
if __name__ == '__main__':
s1 = S()
s2 = S()
print(id(s1))
print(id(s2))
这里我们运行后, 可以看大id(s1)
和 id(s2)
的结果是一样的, 说明两次实例化返回的是相同的实例
静态方法调用
在PHP里, 可以通过静态类方法调用得到单例, 在python里也可以这么做
class S(object):
@classmethod
def get_ins(cls):
if hasattr(cls, 'ins'):
return cls.ins
cls.ins = cls()
return cls.ins
if __name__ == '__main__':
s1 = S.get_ins()
s2 = S.get_ins()
print(id(s1)) # 4517777872
print(id(s2)) # 4517777872
这里我们得到的也是id(s1)
和 id(s2)
一样的, 也能得到单例
模块引入方式
我们知道在python在引入模块的变量时, 只会引入一次, 基于这个特性, 我们也可以实现单例
s.py
模块中
class A(object):
pass
a = A()
ins.py
模块中
import s
a1 = s.a
a2 = s.a
if __name__ == '__main__':
print(id(a1)) # 4310632656
print(id(a2)) # 4310632656
可以看到, 得到的也是相同的实例