python的单例模式 Singleton
使用元类metaclass来创建单例
元类(metaclass)可以控制类的创建过程,它主要做三件事:
-
拦截类的创建
-
修改类的定义
-
返回修改后的类
说明一下python中几个特殊的方法和名词的解释:
__new__()
方法的作用是为类的对象分配内存空间; 一般不会去重写该方法,除非你确切知道怎么做,什么时候你会去关心它呢,它作为构造函数用于创建对象,是一个工厂函数,专用于生产实例对象。著名的设计模式之一,单例模式,就可以通过此方法来实现。在自己写框架级的代码时,可能你会用到它,我们也可以从开源代码中找到它的应用场景,例如微型 Web 框架 Bootle 就用到了
__init__()
方法的作用是为类对象进行初始化
__call__()
方法的作用是使类实例对象能够像函数一样来调用,因此在创建类的对象的时候就会调用__call__()
注意:如果__new__()没有返回cls(即当前类)的实例,那么当前类的__init__()方法是不会被调用 的。如果__new__()返回其他类(新式类或经典类均可)的实例,那么只会调用被返回的那个类的__init__()构造方法
另外,__init__方法中除了self之外定义的参数,都将与__new__方法中除cls参数之外的参数是必须保持一致或者等效。
super():返回其上一级父类的方法
type:是元类,即所有类的基础类。可以用__metaclass__ 来标识
如果想自己定义的类是单例形式,只要从Singleton类继承即可
创建单例的两种方式:
方式1:
class Singleton(type):
def __new__(cls, name,bases,attrs):
print "run __new__() ...."
cls.__instance = None
return super(Singleton,cls).__new__(cls,name,bases,attrs)
def __call__(self, *args, **kwargs):
print "run __call__() ..."
if self.__instance is None:
print "返回单例对象..."
self.__instance = super(Singleton,self).__call__(*args, **kwargs)
return self.__instance
class MyClass(object):
__metaclass__ = Singleton
def __init__(self, name):
print "run __init()__ ..."
self.name = name
def get_name(self, name):
return self.name
dp_1 = MyClass("nlj")
dp_2 = MyClass("wangwu")
print dp_1.name, id(dp_1)
print dp_2.name, id(dp_2)
print (dp_1 is dp_2)
运行结果:
run __new__() ....
run __call__() ...
返回单例对象...
run __init()__ ...
run __call__() ...
nlj 140294620061776
nlj 140294620061776
True
方式2:
class Singleton(type):
def __call__(cls, *args, **kwargs):
print 'call Singleton __call__'
if not hasattr(cls, '_instance'):
cls._instance = super(Singleton,cls).__call__(*args, **kwargs)
return cls._instance
class MyClass(object):
__metaclass__ = Singleton
def __init__(self, name):
self.name = name
def get_name(self, name):
return self.name
dp_1 = MyClass("nlj")
dp_2 = MyClass("wangwu")
print dp_1.name, id(dp_1)
print dp_2.name, id(dp_2)
print (dp_1 is dp_2)
返回结果:
nlj 140141010628688
nlj 140141010628688
True