__new__方法
定义一个类,并且创建一个实例对象的代码如下。就这样的几行代码,Python解释器主要做了两件事:(1)、调用__new__()方法给实例对象开辟空间并返回这个对象(2)、调用__init__方法给实例对象的属性赋值。
class Dog:
def __init__(self,name):
self.name = name
dog = Dog()
实际上__new__()方法是object类的方法,因为在Python中所有类的最终父类都是object类,因此Dog类也拥有__new__方法。
单例模式
单例模式就是无论在代码中创建多少个实例对象,但是创建出的对象共同指向内存中的同一个地址,这一点和类属性一样。
根据对以上__new__方法的总结,只要__new__方法只调用一次,就能保证所有的对象实例都指向内存中的同一个地址,因此我们需要重写__new__方法。
class Dog:
def __new__(cls, *args, **kwargs): #这三个参数实际上是解释器自己加上的,是用来传给__init__方法使用的。
pass
def __init__(self,name):
self.name = name
dog1 = Dog("狗1")
dog2 = Dog("狗2")
print(dog1)
print(dog2)
结果:
None
None
如果我们就按上面演示的例子这么写,输出的两个实例对象都是None。这是因为object类的__new__()方法是要开辟内存的,而我们这么写并没有开辟内存。
class Dog:
instance = None # 这个值就是将要创建的单例对象
def __new__(cls, *args, **kwargs): # 这三个参数是解释器自动添加的,这些参数实际上是给__init__方法用的。
if Dog.instance is None: # 如果这个实例对象还是None
Dog.instance = object.__new__(cls) #调用父类的__new__方法来开辟内存
return Dog.instance
def __init__(self,name):
self.name = name
dog1 = Dog("狗1")
dog2 = Dog("狗2")
print(dog1)
print(dog2)
结果:
<__main__.Dog object at 0x018E14F0>
<__main__.Dog object at 0x018E14F0>
因为类对象在本质上就符合单例模式所说的指向同一块内存,因此这里使用类对象来保存即将要创建的单例对象。