什么是单例模式?
单例模式是一种创建型设计模式,它保证一个类只有一个实例,并提供一个全局访问点来访问该实例
下面看一下最初代码:(具体内容可以参看之前的文章https://mp.csdn.net/mp_blog/creation/editor/136640949)
python
class MyType(type):
def __init__(self, name, bases,attrs):
super().__init__(name, bases,attrs)
def __call__(self, *args, **kwargs):
# 调用本类的__new__方法去创建对象
empty_obj = self.__new__(self)
# 调用本类中的__init__方法初始化Foo类
self.__init__(empty_obj, *args, **kwargs)
return empty_obj
class Foo(object, metaclass=MyType):
pass
下面我想实现单例模式就可以:
在创建类Foo的时候创建一个类变量,用于存储刚开始创建的对象,并且后续在程序中再创建一次只会得到同一个对象
那该在哪修改呢?
可以在Foo的元类中进行修改,在元类MyType调用new和init创建类时进行一些扩展
具体怎么做呢?
- 在元类初始化的时候创建一个变量instance,让他的默认值为None,该变量用来判断是否创建过对象
python
def __init__(self, name, bases,attrs):
super().__init__(name, bases,attrs)
# 初始设置该变量为None,表示没有创建过对象
self.instance = None
- 当Foo类实例化的时候,会调用元类的call方法,我们将call方法中的init方法稍作变化,优先判断是否有对象,没有才创建
python
def __call__(self, *args, **kwargs):
# 判断是否已有对象,没有则创建
if self.instance is None:
self.instance = self.__new__(self)
self.__init__(self.instance, *args, **kwargs)
return self.instance
此时测试一下同时利用Foo实例化两次的结果:地址完全相同
python
v1 = Foo()
v2 = Foo()
print(v1) # <__main__.Foo object at 0x00000260EB61CF90>
print(v2) # <__main__.Foo object at 0x00000260EB61CF90>
此外,需要注意的是,当子类继承父类时,父类的元类即是子类的元类