Python单例模式
单例模式是最常见的一种设计模式,该模式确保系统中一个类有且仅有一个实例
常用的三种实现方式如下:
1、使用模块(推荐)
模块是天然单例的,因为模块只会被加载一次,加载后,其他脚本若导入使用时,会从sys.modules
中找到已加载好的模块,多线程下也是如此
编写Singleton.py
脚本:
class MySingleton():
def __init__(self, name, age):
self.name = name
self.age = age
其他脚本导入使用:
from Singleton import MySingleton
single1 = MySingleton('Tom', 18)
single2 = MySingleton('Bob', 20)
print(single1 is single2) # True
2、使用装饰器
可以通过装饰器装饰需要支持单例的类
from threading import RLock
def Singleton(cls):
single_lock = RLock()
instance = {}
def singleton_wrapper(*args, **kwargs):
# 加锁
with single_lock:
if cls not in instance:
instance[cls] = cls(*args, **kwargs)
return instance[cls]
return singleton_wrapper
@Singleton
class MySingleton(object):
def __init__(self, name, age):
self.name = name
self.age = age
# 该方式线程不安全,需要加锁校验
single1 = MySingleton('Tom', 18)
single2 = MySingleton('Bob', 20)
print(single1 is single2) # True
在装饰器的闭包函数中,判断字典是否已经有类和类实例的键值对。如果没有,则添加一个类和类实例的键值对,如果有,则返回字典中的类实例
3、使用new()方法
Python的__new__()
方法是用来创建实例的,可以在其创建实例的时候进行控制
class MySingleton(object):
single_lock = RLock()
def __init__(self, name, age):
self.name = name
self.age = age
def __new__(cls, *args, **kwargs):
# 加锁
with MySingleton.single_lock:
if not hasattr(MySingleton, '_instance'):
MySingleton._instance = super().__new__(cls)
return MySingleton._instance
single1 = MySingleton('Tom', 18)
single2 = MySingleton('Bob', 20)
print(single1 is single2) # True
以下代码可帮助理解上述代码:
class MySingleton(object):
_instance = None
single_lock = RLock()
def __new__(cls, *args, **kwargs):
# 加锁
with MySingleton.single_lock:
if cls._instance is None:
cls._instance = super().__new__(cls)
return cls._instance
def __init__(self, name, age):
self.name = name
self.age = age
single1 = MySingleton('Tom', 18)
single2 = MySingleton('Bob', 20)
print(single1 is single2) # True
在Python类中,每次实例化一个类对象时,都会自动先执行__new__
方法再执行__init__
方法。__new__
方法先在内存中为实例对象申请空间,然后__init__
方法初始化实例对象
因为__init__
方法是在__new__
执行完成后自动执行的,每次实例化类的对象时都会执行__init__
方法,所以也要对__init__
方法进行重写,只有第一次实例化类对象时才执行初始化操作
通过重写__new__
方法,如果这个类没有实例对象,则执行__new__
,否则直接返回已有的实例,从而实现单例