##单例模式 只初始化一次
单例模式创建的原理就是借用了私有类属性的性质,我们知道私有类属性不能直接在类外被修改,所以用私有类属性的状态当做条件来控制类内方法的调用
方法一:
下面代码中的__species负责控制__new__方法,保证实例对象只能被创建一次,创建多个对象,均指向同一个数据内存位置
__first_init负责控制__init__方法,保证再次创建的对象不能更改初始化的内容
class Animal(object):
__species = None
__first_init = True
def __new__(cls, *args, **kwargs):
if cls.__species == None:
cls.__species = object.__new__(cls)
return cls.__species
def __init__(self,name):
print("-----init----")
if self.__first_init:
self.name = name
self.__class__.__first_init = False
# 相当于Animal.__first_init = False
def __str__(self):
return "-------str---%s" %self.name
if __name__ == '__main__':
dog = Animal('二哈')
print(dog)
print(id(dog))
dog2 = Animal('金毛')
print(dog)
print(id(dog2))
执行结果:
-----init----
-------str---二哈
139764904013104
-----init----
-------str---二哈
139764904013104
调用new方法必须要有return, 返回创建的实例对象或者是父类的__new__方法创建实例对象
由执行结果可知,两次创建的实例对象指向了同一个id,即 创建单例模式
第二次创建的实例对象dog2“金毛”,并未创建成功,仍然是第一次创建出来的实例对象dog"二哈",即 初始化一次
方法二:
import functools
def singleton(cls):
_instances = {}
@functools.wraps(cls)
def get_instance(*args, **kwargs):
if cls not in _instances:
_instances[cls] = cls(*args, **kwargs)
return _instances[cls]
return get_instance
@singleton
class Animal:
def __init__(self, name):
print("-----init----")
self.name = name
def __str__(self):
return "-------str---%s" % self.name
if __name__ == '__main__':
dog = Animal('二哈')
print(dog)
print(id(dog))
dog2 = Animal('金毛')
print(dog)
print(id(dog2))
执行结果:
-----init----
-------str—二哈
4327353816
-------str—二哈
4327353816