前述
在近日的日常开发中,有一个需求是通过外部的配置项来控制当前的类是否使用单例模式.
普通的单例实现
个人觉得最常用的就是可以通过__new__来实现,python在加载类实例的时候会先调用__new__函数的代码实现。
class SingletonClass(object):
_instance = None
def __new__(cls, *args, **kwargs):
if cls._instance is None:
cls._instance = super(SingletonClass, cls).__new__(cls)
return cls._instance
def __init__(self, name):
self.name = name
元类实现
通过用__new__来实现单例,并不能满足我的需求,这里我们可以通过元类来动态的设置类的单例模式
config_item = True
class SingletonMeta(type):
_instances = {}
def __call__(cls, *args, **kwargs):
if not config_item:
if cls not in cls._instances:
cls._instances[cls] = super(SingletonMeta, cls).__call__(*args, **kwargs)
return cls._instances[cls]
else:
return super(SingletonMeta, cls).__call__(*args, **kwargs)
class MyClass(metaclass=SingletonMeta):
def __init__(self, value):
self.value = value
if __name__ == "__main__":
# 第一次创建实例
instance1 = MyClass(10)
print(instance1) # 输出: MyClass(value=10)
# 测试配置项为True的情况
config_item = True
instance2 = MyClass(20)
print(instance2) # 若配置项为True,输出: MyClass(value=10)
print(instance1 is instance2) # 输出: True
-
外部(全局)变量:用于控制是否使用单例模式。
-
元类
SingletonMeta:- 使用
_instances字典来存储单例实例。 - 重写
__call__方法,该方法在类实例化时被调用。 - 根据
USE_SINGLETON的值决定是返回现有实例还是创建新实例。
- 使用
-
类
MyClass:使用SingletonMeta作为其元类。
通过这种方式,可以动态地控制类是否应该使用单例模式。